Question 1
Construct the status matrix
add deal year information to investor/deal data
#no missing value for lead_investor
unique(data4$Lead_Investor)
[1] 0 1
#all qulified deal
dataclean <- merge(data4[,c(1,2,4)],data2[,c(1,32)],by="Deal_Id")
incidence matrix
#only consider co-investment
d1 <- dataclean %>%
group_by(Deal_Id) %>%
summarise(count=length(unique(Investor_Id)))
##find co-investment event
d2 <- d1[which(d1$count>1),]
##keep only data for co-investment
d3 <- dataclean[which(dataclean$Deal_Id%in%d2$Deal_Id),]
##not all co-investment events have lead investor
t1 <- d3 %>%
group_by(Deal_Id)%>%
summarise(sum=sum(Lead_Investor))
t2 <- t1[which(t1$sum>0),]
yearlist <- sort(unique(d3$Year))
#method1
#try to store adj matrix in a list but memory not enough and take too long to run
#construct incidence matrix for co-investments and transform it to adj matrix by year
#sharemtx1 <- list()
#for(i in 1:length(yearlist)){
# yearsel<-yearlist[i]
# g1 <- d4[which(d4$Year==yearsel),]
# g2 <- as.matrix(data.frame(dcast(g1[,c(1,2)], Investor_Id ~ Deal_Id, fun.aggregate=length), row.names = 1))
# g3 <- g2%*%t(g2)
# diag(g3) <- 0
# sharemtx1[[i]] <- g3
#}
#method2
#1. construct incidence matrix for co-investments
#2. transform it to adj matrix by year
#3. transform it to edge list with weight and year
#use tcrossprod() and sparse matrix for faster matrix multiplication
shareedgelist <- data.table()
for(yearsel in yearlist){
g1 <- d3[which(d3$Year==yearsel),]
g2 <- as.matrix(data.frame(dcast(g1[,c(1,2)], Investor_Id ~ Deal_Id, fun.aggregate=length), row.names = 1),sparse = TRUE)
g3 <- tcrossprod(g2,g2)
diag(g3) <- 0
g4<- graph.adjacency(g3,weighted=TRUE,mode = "undirected")
res <- get.data.frame(g4)
res$year <- yearsel
shareedgelist <- rbind(shareedgelist,res)
}
#for each year, consider recent 5 year co-investment count
sharecount <- data.table()
for(yearsel in yearlist){
g1 <- shareedgelist[which((shareedgelist$year<=yearsel)&(shareedgelist$year>yearsel-5)),] %>%
group_by(from,to) %>%
summarise(year=yearsel,count=sum(weight))
sharecount <- rbind(sharecount,as.data.frame(g1))
}
#write.csv(sharecount,"sharecount.csv")
#lead investment
leadedgelist <- data.table()
d4 <- d3[which(d3$Deal_Id%in%t2$Deal_Id),]
coinvestlist <- unique(d4$Deal_Id)
for(dealsel in coinvestlist){
g1 <- d4[which(d4$Deal_Id==dealsel),]
g2 <- expand.grid(unlist(g1[which(g1$Lead_Investor==1),2]),unlist(g1[,2]))
g2$year <- g1$Year
leadedgelist <- rbind(leadedgelist,g2)
}
colnames(leadedgelist) <- c("lead","non","year")
#write.csv(leadedgelist,"leadedgelist.csv")
#for each year, consider recent 5 year co-investment lead count
leadcount <- data.table()
for(yearsel in yearlist){
g1 <- leadedgelist[which((leadedgelist$year<=yearsel)&(leadedgelist$year>yearsel-5)),] %>%
group_by(lead,non) %>%
summarise(year=yearsel,count=n())
leadcount <- rbind(leadcount,as.data.frame(g1))
}
#adjust data type
leadcount$lead <- as.character(leadcount$lead)
leadcount$non <- as.character(leadcount$non)
#make sure to have the dia value equal to 0
leadcount <- leadcount[which(leadcount$lead!=leadcount$non),]
colnames(leadcount) <- c("lead","non","year","leadshare")
#write.csv(leadcount,"leadcount.csv")
#construct whole sharecount list
#have v1 -> v2 and v2 -> v1
sharecount <- sharecount[which(sharecount$from!=sharecount$to),]
sharecount1 <- cbind(sharecount[,2],sharecount[,1],sharecount[,c(3,4)])
colnames(sharecount1) <- c("from","to","year","count")
sharecount <- rbind(sharecount,sharecount1)
colnames(sharecount) <- c("lead","non","year","countshare")
#combine share and co-investment information
status <- merge(sharecount,leadcount,by=c("lead","non","year"),all.x = TRUE)
status[which(is.na(status$leadshare)),5] <- 0
#as defination
status$value <- status$leadshare/status$countshare
status1 <- status[,c(1,2,3,5)]
colnames(status1)[4]<-"weight"
#get eiigenvector centrality of the matrix as status
status2 <- data.table()
for(yearsel in yearlist){
g1 <- status1[which(status1$year==yearsel),c(1,2,4)]
g2 <- graph.data.frame(g1,directed=TRUE)
g3 <- eigen_centrality(g2, directed = TRUE, weights = NULL)$vector
g4 <- as.data.table(cbind(names(g3),unname(g3)))
g4$year <- yearsel
status2 <- rbind(status2,g4)
}
#write.csv(status2,"status2.csv")
Question1A
Traditionally, venture capital analysis have only considered the concentration of a venture capital firms investments in to different portfolio categories. The more concentrated a firm’s investments, the less diversified it is.
calculate Herfindahl index
#unique category
categorylist <- unique(data1$Primary_Industry_Code)
#load lpackage hhi for herfindahl index calculation
library("hhi")
#combine whole qualified deal data and company type data
data5 <- merge(dataclean,data2[,c(1,2)],by="Deal_Id",all.x = TRUE)
colnames(data5)[5]<-"CompanyID"
data5 <- merge(data5,data1[,c(1,8)],by="CompanyID",all.x = TRUE)
#group by each year/firm for percentage of each sector
data6 <- data5 %>%
group_by(Investor_Id,Year,Primary_Industry_Code) %>%
summarise(count=n())%>%
group_by(Investor_Id,Year) %>%
mutate(Percentage=count/sum(count)*100)
#table concentration to store herfindahl index
concentration <- unique(data6[,c(1,2)])
concentration$con <- NA
#get concentration
for(i in (1:dim(concentration)[1])){
g1 <- data6[(which((data6$Investor_Id==concentration[i,]$Investor_Id)&(data6$Year==concentration[i,]$Year))),c(3,5)]
g2 <- hhi(as.data.frame(g1),"Percentage")
concentration[i,3] <- g2
}
#import saved data from above code
concentration <- fread("concentration.csv", header = TRUE)[,c(2:4)]
control variable 1 whether a venture capital firm tends to originate its own deals: for more than 50% of the companies it invests in, it invests in the first investment round this company has received
datac1 <- data5
datac1[, first_round := ifelse(Year==min(Year),1,0), by=list(CompanyID)]
#group by each year/firm for number of total investment and if first_round
datac1r <- datac1 %>%
group_by(Investor_Id,Year) %>%
summarise(yearinvestment=n(),yearfirst=sum(first_round))%>%
group_by(Investor_Id) %>%
mutate(total=cumsum(yearinvestment),totalfirst=cumsum(yearfirst))
datac1r <- as.data.table(datac1r)
#if more than 50% are in the first investment round
datac1r[,first_round := ifelse(totalfirst/total>0.5,1,0)]
control variable 2 whether a venture capital ???rm tends to invest in the IT sector: more than 50% of the companies it invests in are in the company-level variable Primary Industry Sector “Information Technology”
datac2 <- data5
datac2 <- merge(datac2,data1[,c(1,6)],by="CompanyID",all.x = TRUE)
datac2[, IT := ifelse(Primary_Industry_Sector=="Information Technology",1,0)]
#group by each year/firm for number of total investment and if IT
datac2r <- datac2 %>%
group_by(Investor_Id,Year) %>%
summarise(yearinvestment=n(),yearit=sum(IT))%>%
group_by(Investor_Id) %>%
mutate(total=cumsum(yearinvestment),totalit=cumsum(yearit))
datac2r <- as.data.table(datac2r)
#if more than 50% are in IT sector
datac2r[,IT := ifelse(totalit/total>0.5,1,0)]
control variable 3 whether a venture capital firm tends to invest in early-stage startups: more than 50% of the companies it invests in are of the Deal Type 1 “Early Stage VC”, “Accelerator/Incubator”, “Seed Round”, or “Angel (individual)”
datac3 <- data5
datac3 <- merge(datac3,data2[,c(1,9)],by="Deal_Id",all.x = TRUE)
datac3[, type := ifelse(Deal_Type_1=="Early Stage VC"|Deal_Type_1=="Accelerator/Incubator"|Deal_Type_1=="Seed Round"|Deal_Type_1=="Angel (individual)",1,0)]
#group by each year/firm for number of total investment and if specific types
datac3r <- datac3 %>%
group_by(Investor_Id,Year) %>%
summarise(yearinvestment=n(),yeartype=sum(type))%>%
group_by(Investor_Id) %>%
mutate(total=cumsum(yearinvestment),totaltype=cumsum(yeartype))
datac3r <- as.data.table(datac3r)
#if more than 50% are in early stage startups
datac3r[,early := ifelse(totaltype/total>0.5,1,0)]
merge regression data together
q1a <- merge(datac1r,datac2r,by=c("Investor_Id","Year"))
q1a <- merge(q1a,datac3r,by=c("Investor_Id","Year"))
q1a <- q1a[,c(1,2,7,12,17)]
colnames(status2) <- c("Investor_Id","score","Year")
q1a <- merge(q1a,status2,by=c("Investor_Id","Year"))
q1a <- merge(q1a,concentration,by=c("Investor_Id","Year"))
get lag value for control variables and status variable
q1a$score <- as.numeric(q1a$score)
q1a <-
q1a %>%
group_by(Investor_Id) %>%
mutate(lag_status = dplyr::lag(score, n = 1, default = NA),lag_early = dplyr::lag(early, n = 1, default = NA),
lag_IT = dplyr::lag(IT, n = 1, default = NA),lag_first = dplyr::lag(first_round, n = 1, default = NA))
q1areg <- q1a[,c(1,2,7:11)]
q1areg1 <- as.data.table(na.omit(q1areg))
regression
summary(plm(con ~ lag_status + I(lag_status^2)+ lag_first + lag_IT + lag_early + Year, q1areg1, effect = "individual", model = "within", index = "Investor_Id"))
Oneway (individual) effect Within Model
Call:
plm(formula = con ~ lag_status + I(lag_status^2) + lag_first +
lag_IT + lag_early + Year, data = q1areg1, effect = "individual",
model = "within", index = "Investor_Id")
Unbalanced Panel: n = 6035, T = 1-28, N = 34247
Residuals:
Min. 1st Qu. Median 3rd Qu. Max.
-6886.65 -1677.42 -230.54 1330.56 10190.24
Coefficients:
Estimate Std. Error t-value Pr(>|t|)
lag_status -12030.2115 493.0356 -24.4003 < 2.2e-16 ***
I(lag_status^2) 13193.8246 683.8708 19.2929 < 2.2e-16 ***
lag_first -403.8876 51.1487 -7.8963 2.976e-15 ***
lag_IT 49.0139 58.3381 0.8402 0.4008
lag_early -507.9551 53.5589 -9.4840 < 2.2e-16 ***
Year -47.4435 4.2953 -11.0454 < 2.2e-16 ***
---
Signif. codes: 0 â***â 0.001 â**â 0.01 â*â 0.05 â.â 0.1 â â 1
Total Sum of Squares: 2.1274e+11
Residual Sum of Squares: 2.059e+11
R-Squared: 0.032138
Adj. R-Squared: -0.17512
F-statistic: 156.097 on 6 and 28206 DF, p-value: < 2.22e-16
INSIGHT
What is the relationship between status and diversification?
According to above regression, lag_status has negative effect and the square of lag_status has positive effect on the concentration level of the investments of a venture capital at the confidence level of 0 which is highly significant. It suggests that at first, the increase of a firm’s status contributes to the diversification of its investments, but when the status reach a certain level, the increase of a firm’s status tends to lower the diversification of the firm’s investments.
Take control variables into account, both first_round and early_stage show significant negtive effect on the concentration level. We can conclude that with same status in the previous year, a firm that tends to originate its own deals or tends to invest in early-stage startups is more likely to have more diversified investment profile in this year.
Question 1b
Create a new measure of diversi???cation that takes the relatedness of industry categories into account. First compute the relatedness of each industry category as the Jaccard distance between each pair of industry categories for each year, using the company-level variable “Primary Industry Code”. Base the similarity on the co-occurrence of industry categories in investors’ portfolios cumulative to the current year.
#new table to store niche_width value for each year each firm
niche_width <- data.table()
data1b <- data5[,c(3,5,6)]
#get relatedness each industry category as the jacard distance between each pair of industry categories for each year
for(yearsel in yearlist){
subpair <- data1b[data1b$Year<=yearsel,c(1,3)]
g1 <- data.frame(dcast(subpair, Primary_Industry_Code ~ Investor_Id,fun.aggregate=length), row.names = 1)
g1[g1>1] <- 1
#get dist matrix
g2 <- as.matrix(dist(g1))
#get industry combination for each investor
subin <- unique(subpair)
subin[, indcount := .N , by ='Investor_Id']
#get total industry
res1 <- unique(subin[,c(1,3)])
#only consider investors that have invested in more than one type of industries
subin1 = subin[indcount>1]
#combination
comb<- subin1[,as.data.table(t(combn(Primary_Industry_Code,2))), by='Investor_Id']
comb<- as.data.frame(comb)
comb <-comb[complete.cases(comb), ]
comb <- comb[!((comb$V1=="") | comb$V2==""), ]
for(i in (1:nrow(comb))){
comb[i,'distance']<- g2[comb[i,2],comb[i,3]]
}
#sum distance
res <- comb %>%
group_by(Investor_Id)%>%
summarise(sum_dist=sum(distance))
resw <- merge(res1,res,by="Investor_Id",all.x = TRUE)
resw$Year <- yearsel
niche_width <- rbind(niche_width,resw)
}
#write.csv(niche_width,"niche_width.csv")
regression
niche_width$nw <- 1-(1/(1+niche_width$sum_dist/(niche_width$indcount-1)))
niche_width <- as.data.table(niche_width)
#If an investor only invests in a single industry category, set the niche_width equal to 0
niche_width[which(is.na(niche_width$nw)),5]<-0
q1b <- merge(q1a,niche_width[,c(1,4,5)],by=c("Investor_Id","Year"))
q1b <- as.data.table(q1b)
#The approach for incorporating fixed effects for this model is different: include in the model the average values for all of the predictors, except for the year, for each firm over itslifetime.
q1b[,avg_status:= mean(score,na.rm=TRUE), by=Investor_Id]
q1b[,avg_status_squared := mean(score^2,na.rm=TRUE), by=Investor_Id]
q1b[,avg_First_Round:= mean(first_round,na.rm=TRUE), by=Investor_Id]
q1b[,avg_IT_Sector:= mean(IT,na.rm=TRUE), by=Investor_Id]
q1b[,avg_Early_Stage:= mean(early,na.rm=TRUE), by=Investor_Id]
#regression
summary(glm(nw ~ lag_status + I(lag_status^2)+ lag_first + lag_IT + lag_early + avg_status + avg_status_squared+avg_First_Round + avg_IT_Sector + avg_Early_Stage + Year, q1b, family = quasibinomial(link = "logit")))
Call:
glm(formula = nw ~ lag_status + I(lag_status^2) + lag_first +
lag_IT + lag_early + avg_status + avg_status_squared + avg_First_Round +
avg_IT_Sector + avg_Early_Stage + Year, family = quasibinomial(link = "logit"),
data = q1b)
Deviance Residuals:
Min 1Q Median 3Q Max
-3.6465 0.0159 0.0913 0.1690 0.8609
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -2.761e+02 1.026e+01 -26.906 <2e-16 ***
lag_status 1.161e+01 1.336e+00 8.689 <2e-16 ***
I(lag_status^2) -1.236e+01 1.383e+00 -8.939 <2e-16 ***
lag_first -7.000e-01 6.798e-02 -10.297 <2e-16 ***
lag_IT -2.118e-02 8.399e-02 -0.252 0.8009
lag_early -1.584e-01 7.111e-02 -2.228 0.0259 *
avg_status 2.243e+01 1.343e+00 16.696 <2e-16 ***
avg_status_squared -2.384e+01 1.762e+00 -13.529 <2e-16 ***
avg_First_Round 2.186e+00 9.297e-02 23.512 <2e-16 ***
avg_IT_Sector 1.627e-01 9.705e-02 1.677 0.0936 .
avg_Early_Stage -6.746e-02 9.162e-02 -0.736 0.4615
Year 1.385e-01 5.112e-03 27.100 <2e-16 ***
---
Signif. codes: 0 â***â 0.001 â**â 0.01 â*â 0.05 â.â 0.1 â â 1
(Dispersion parameter for quasibinomial family taken to be 0.4581126)
Null deviance: 4811.9 on 25797 degrees of freedom
Residual deviance: 3728.8 on 25786 degrees of freedom
(6634 observations deleted due to missingness)
AIC: NA
Number of Fisher Scoring iterations: 8
INSIGHT
What is the relationship between status and diversification?
According to above regression result, the lag value of status have positive effect and it’s square term have negative effect on the level of dicersification of a firm’s investments with significant on 0 confidence level. It suggests that venture capital with high and low status both have lower diversification level in their investment profolio while middle status venture capital tends to have higher diversification level in their investment profolio.
Take control variable into account, the lag value of a firm’s tendency of investing in first round and early stage show negative effect with significance. We can conclude that with same status in the previous year, a firm that tends to originate its own deals or tends to invest in early-stage startups is more likely to have less diversified investment profile in this year.
Question 1c
Next, let’s check the shape of the regression curve to get a sense of the parabolic curvature.
#First, re-run the regression from 1B just using lagged status and the status squared term and not using any of the additional controls.
reg_1c <-glm(nw ~ lag_status + I(lag_status^2), q1b, family = quasibinomial(link = "logit"))
#set up a data object with a range of values of the lagged status variableâ100 values ranging from the minimum to the maximum of this variable.
data <- data.frame(seq(min(q1b$lag_status,na.rm=TRUE), max(q1b$lag_status,na.rm=TRUE), length = 100))
colnames(data) <- 'lag_status'
preds <-predict(reg_1c,data,se.fit = TRUE)
# Plot
plot(x = data$lag_status, y = preds$fit,type = 'l',xlab="Lagged Status", ylab="Diversiï¬cation (Niche Width)")
polygon(c(data$lag_status,rev(data$lag_status)),c(preds$fit-1.95*preds$se.fit,rev(preds$fit+1.95*preds$se.fit)),col = rgb(1, 0, 0,0.5), border = NA)
lines(x= data$lag_status, y = preds$fit+1.96*preds$se.fit, lty = 'dashed', col = 'blue')
lines(x= data$lag_status, y = preds$fit-1.96*preds$se.fit, lty = 'dashed', col = 'blue')

INSIGHT
What does the curve suggest about the diversification strategies of low, middle, and high-status venture capital firms?
The curve suggests that high-status venture capital and low status venture capital hiave lower diversification in their investment profolio while middle status venture capital firms tend to have higher diversification. Firms with extrem high status have even lower diversification strategies compared to firms with extrem low status.
As we also plot the 95% confidence intervals for the fitted values, we can observe from the plot that middle-status venture capital are more varied in their level of diversification while low-status venture capital do not vaired much in the diversification strategies.
Question 2
Which venture capital firms are more effective at diversifying their portfolios?
A
data2a <- datac3
data2a[, type := ifelse(Deal_Type_1=="Merger/Acquisition"|Deal_Type_1=="IPO"|Deal_Type_1=="Buyout/LBO",1,0)]
#group by each year/firm for number of cum successful investment
data2ar <- data2a %>%
group_by(Investor_Id,Year) %>%
summarise(yearsucc=sum(type))%>%
group_by(Investor_Id) %>%
mutate(totalsucc=cumsum(yearsucc))
data2ar <- as.data.table(data2ar)
#regression
#Run a appropriate regression,considering the form of the outcome variable and incorporating venture capital firm fixed effects, predicting the number of successful investments as a function of lagged status, lagged diversification, and interaction of lagged status and lagged diversification.
#Use the niche width measure of diversification and include the same controls from the regressions from 1A and 1B.
#get lag diversification
q2a <- merge(q1b,data2ar,by=c("Investor_Id","Year"))
q2a <- q2a %>%
group_by(Investor_Id) %>%
mutate(lag_nw = dplyr::lag(nw, n = 1, default = NA))
# Regression
summary(glm(totalsucc â¼ lag_status + lag_nw + lag_status:lag_nw + lag_first + lag_IT + lag_early + Year , q2a,family = poisson))
Call:
glm(formula = totalsucc ~ lag_status + lag_nw + lag_status:lag_nw +
lag_first + lag_IT + lag_early + Year, family = poisson,
data = q2a)
Deviance Residuals:
Min 1Q Median 3Q Max
-7.6225 -1.0865 -0.7186 -0.1092 21.2759
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -2.553e+02 4.491e+00 -56.836 < 2e-16 ***
lag_status -1.999e+01 4.488e+00 -4.453 8.47e-06 ***
lag_nw 4.152e+00 1.979e-01 20.983 < 2e-16 ***
lag_first 5.553e-01 1.677e-02 33.103 < 2e-16 ***
lag_IT -2.780e-02 1.619e-02 -1.717 0.086 .
lag_early -1.529e+00 1.732e-02 -88.260 < 2e-16 ***
Year 1.249e-01 2.247e-03 55.610 < 2e-16 ***
lag_status:lag_nw 2.389e+01 4.504e+00 5.304 1.13e-07 ***
---
Signif. codes: 0 â***â 0.001 â**â 0.01 â*â 0.05 â.â 0.1 â â 1
(Dispersion parameter for poisson family taken to be 1)
Null deviance: 74040 on 25797 degrees of freedom
Residual deviance: 55803 on 25790 degrees of freedom
(6634 observations deleted due to missingness)
AIC: 71037
Number of Fisher Scoring iterations: 9
INSIGHT
Is this interaction related to having more successful investments?
This interaction has positive coefficient with highly siginificance. It suggests that this interaction is related to having more successful investment. Both lag_status and lag_nw(diviersification) have significant effect from the regression, and lag_status has negative effect while lag_nw has positive effect.
It indicates that there is a synergistic effect of the two variables-high levels of both together(high-status with high diversification level of the investment profolio) have a positive effect on the outcome variable-more successful investments.
B
Similar to 1C, we can use a visualization to better understand the relationship between the variables in the regression. We can accomplish this using a 3d scatterplot or a contour plot generated from the ???tted values of the model.
#Re-run a similar model from 2A with just lagged status and lagged diversification and without using firm fixed effects,
#e.g.,using glm()withfamily = "poisson",and assign it to an object.
reg_2b <- glm(totalsucc â¼ lag_status + lag_nw, q2a,family = poisson)
#Next, generate a range ofvalues for lagged status and lagged diversification, similar to 1C. Use the function expand.grid() to range of combinations of status and diversification
data <- data.frame(seq(min(q2a$lag_status,na.rm=TRUE), max(q2a$lag_status,na.rm=TRUE), length = 100),seq(min(q2a$lag_nw,na.rm=TRUE), max(q2a$lag_nw,na.rm=TRUE), length = 100))
colnames(data) <- c('lag_status','lag_nw')
#and then use predict to get the fitted values for each combination of diversification and status. Below is some code that will generate a 3d scatterplot.
data <- expand.grid(data)
preds <-predict(reg_2b,data)
values <- cbind(data,preds)
colnames(values)<-c("status","diversification","successful_investments")
library(rgl)
library(plot3D)
library(plotly)
# regular 3d plot
scatter3D(values$diversification, values$status, values$successful_investments)

# interactive 3d plot
plot3d(values$diversification, values$status, values$successful_investments)
# A contour plot can be executed in a similar manner using the following code, from the plotly package.
colnames(values)<-c("status","niche_width","fit")
p1 = plot_ly(
values,
x = ~status,
y = ~niche_width,
z = ~fit,
type = "contour",
autocontour = FALSE,
contours = list( end = max(values$fit, na.rm = TRUE),
size = abs(max(values$fit, na.rm = TRUE) - min(values$fit, na.rm = TRUE))/20,
start = min(values$fit, na.rm = TRUE), showlines = FALSE ),
line = list(smoothing = 0.85),
colorscale = "Greys"
) %>%
colorbar(len = 1, nticks = 10, title = "Estimated successful \n investments") %>%
layout(yaxis = list(title = "Niche width")) %>%
layout(xaxis = list(title = "Status"))
p1
NA
INSIGHT
What do the patterns suggest about which venture capital firms are most or least successful overall at diversifying their portfolios?
According to above patterns, we can conclude that firms with lower status, lower diversification level tend to have more successful investment. It suggests that with same amount of successful investments, low-status venture capitals diversify their portfolios more effective and have higher level of diversification.
Question 3
The parabolic relationships from 1B and 1C suggest that low and high-status venture capital firms may share similar tendencies to diversify, but the estimates from 2A suggest that highstatus firms are better at diversifying. Why might this be the case?
#no time to run this part of code but have thought about the logic and show here
# Create an empty datatable to store information about each investor's coordinates
coord <- data.table()
for(i in yearlist){
# For each year, take a sub-dataset of previous years.
invest_sub <- as.data.table(subset(data5, year<=i))
# First create an affiliation matrix. 1 indicates that this industry category has occured in the firm's portfolio.
jac_dist <- as.data.frame(invest_sub[,c(3,6)])
jac_dist <- unique(na.omit(jac_dist))
jac_dist$occur <- 1
jac_dist_matrix <- acast(jac_dist,Investor_Id ~ Primary_Industry_Code,value.var="occur")
jac_dist_matrix[is.na(jac_dist_matrix)] = 0
jac_dist_matrix[jac_dist_matrix>=1] = 1
# Use a multidimensional scaling of two dimensions to determine the position
coord_result <-as.data.frame(cmdscale(as.data.frame(as.matrix(proxy::dist(jac_dist_matrix,method ="jaccard")))))
colnames(coord_result) <- c('C1','C2')
coord_result$Investor_Id <- rownames(jac_dist_matrix)
# Combine this year's information to the main concentration_score datatable
coord_result$year <- i
coord <- rbind(coord, coord_result)
}
coord <- fread("coord.csv",header = TRUE)
industry_medoids <- data5[,c("Investor_Id","Deal_Id","Primary_Industry_Code","Year")]
industry_medoids <- as.data.table(industry_medoids)
industry_medoids[,count:=.N, by=c("Year","Primary_Industry_Code","Investor_Id")]
# If a venture capital firm that only invests in that category in a particular year, it should instead become the medoid.
industry_medoids[,medoid:= ifelse(length(unique(Primary_Industry_Code))==1,1,0), by=c('Year','Investor_Id')]
# Check whether there is a medoid for this industry after the first step.
industry_medoids[,medoid_exist:= ifelse(sum(medoid)>0,1,0), by=c('Year','Primary_Industry_Code')]
# Then if no ???rms invest exclusively in the category, I just used as the medoid the ???rm with the most investments in this category.
industry_medoids[,medoid:= ifelse(medoid_exist==0,count==max(count),medoid),by=c('Year','Primary_Industry_Code')]
# Double cheCK there is a medoid for every row's category.
industry_medoids[,medoid_exist2:= ifelse(sum(medoid)>0,1,0), by=c('Year','Primary_Industry_Code')]
# Only keep medoid of industry category in the data table
industry_medoids <- industry_medoids[medoid==1][,c(1,3,4)]
industry_medoids <- left_join(industry_medoids, coord[,c(2:5)], by=c('Year','Investor_Id'))
# Only keep one medoid for each categroy in each year
industry_medoids <- as.data.table(industry_medoids)
industry_medoids <- industry_medoids[, head(.SD, 1), by=c('Year','Primary_Industry_Code')]
colnames(industry_medoids)[3:5] <- c('Medoid',"Medoid_C1","Medoid_C2")
# Join coordinates of each deal and medoid coordinate of each category back to the main data table
data3a <- data5
data3a <- left_join(data3a, coord, by=c('year','Investor_Id'))
data3a <- left_join(data3a, industry_medoids[,c(1,2,4,5)], by=c('year','Primary_Industry_Code'))
data3a <-as.data.table(data3a)
# For each deal, de???ne the distance between a ???rm's experience and the industry category
data3a[,experience_diffence:= sqrt((Medoid_C1-C1)^2+(Medoid_C2-C2)^2)]
# Calculate the average distance between a ???rm's syndicate partners and the industry category medoids for the deals that it invests in in a given year
# First sum the differences by deal each year
data3a[,Deal_Sum:= sum(experience_diffence),by=c('Year','Deal_Id')]
# Then sum the differences of all the deals that an investor invest in each year
data3a[,Investor_Partners_Sum:=sum(Deal_Sum),by=c('Year','Investor_Id') ]
regression
#Run a appropriate regression, considering the form of the outcome variable and incorporating venture capital ???rm ???xed effects, predicting the average distance between a ???rm's syndicate partners and the industry category medoids for the deals that it invests ininagivenyear,as a function of a firm's lagged status,the firm's own average distance from the industry category medoids for the deals that it invests in in a given year, and the interaction between these stwo variables.
summary(lm(avg_partner_distances ??? avg_own_distances + lag_status + avg_own_distances:lag_status + lag_first + lag_IT + lag_early + Year, data3a))
B
same method with question 2
# regular 3d plot
plotq3 <- scatter3D(values$own_distance_from_the_industry_categories, values$status, values$partners_distance_from_the_industry_Scategories)
# interactive 3d plot
plotq3d <- plot3d(values$own_distance_from_the_industry_categories, values$status, values$partners_distance_from_the_industry_Scategories)
#colnames(values)<-c("own_distance_from_the_industry_categories","status","partners_distance_from_the_industry_Scategories")
p3 = plot_ly(
values,
x = ~own_distance_from_the_industry_categories,
y = ~status,
z = ~partners_distance_from_the_industry_Scategories,
type = "contour",
autocontour = FALSE,
contours = list( end = max(values$fit, na.rm = TRUE),
size = abs(max(values$fit, na.rm = TRUE) - min(values$fit, na.rm = TRUE))/20,
start = min(values$fit, na.rm = TRUE), showlines = FALSE ),
line = list(smoothing = 0.85),
colorscale = "Greys"
) %>%
colorbar(len = 1, nticks = 10, title = "Estimated successful \n investments") %>%
layout(yaxis = list(title = "Status")) %>%
layout(xaxis = list(title = "own_distance_from_the_industry_categories"))
#p3
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgNSAtIE1lbmcgQ2hlbmciDQphdXRob3I6ICJNZW5nIENoZW5nIg0KZGF0ZTogIjEyLzIvMjAxOSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCkltcG9ydCByZXF1aXJlZCBwYWNrYWdlDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoaWdyYXBoKQ0KbGlicmFyeShNYXRyaXgpDQpsaWJyYXJ5KGdkYXRhKQ0KbGlicmFyeShwcm94eSkNCmxpYnJhcnkocGxtKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkYXRhLnRhYmxlKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoem9vKQ0KbGlicmFyeShzdHJpbmdyKQ0KYGBgDQoNCkltcG9ydCBkYXRhc2V0IGFuZCBwcmUgY2xlYW4gdGhlIGRhdGENCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI2ltcG9ydCBkYXRhc2V0DQpkYXRhMSA8LSBmcmVhZCgiY29tcGFueV9kZXRhaWxzLmNzdiIsIGhlYWRlciA9IFRSVUUpDQpkYXRhMiA8LSBmcmVhZCgiZGVhbF9kZXRhaWxzLmNzdiIsIGhlYWRlciA9IFRSVUUpDQpkYXRhMyA8LSBmcmVhZCgiaW52ZXN0b3JfZGV0YWlscy5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KZGF0YTQgPC0gZnJlYWQoImludmVzdG9yc19hbmRfZGVhbHMuY3N2IiwgaGVhZGVyID0gVFJVRSkNCg0KI29ubHkgY29uc2lkZXIgaW4gdGhlIGFuYWx5c2lzIGludmVzdG9ycyBvZiB0aGUgVmVudHVyZSBDYXBpdGFsIHR5cGUNCmRhdGEzIDwtIGRhdGEzW3doaWNoKGRhdGEzJEludmVzdG9yX1R5cGU9PSJWZW50dXJlIENhcGl0YWwiKSxdDQoNCg0KI29ubHkgY29uc2lkZXIgZGVhbHMgdGhhdCBoYXZlIG9jY3VycmVkIGZyb20gMTk5MCBvbndhcmQNCiNyZW1vdmUgbWlzc2luZyBkYXRlIGluZm9ybWF0aW9uDQpkYXRhMiA8LSBkYXRhMlt3aGljaChkYXRhMiREZWFsX0RhdGUhPSIiKSxdDQoNCiN0cmFuc2Zvcm0gZGF0ZSBpbnRvIHllYXINCmRhdGEyJFllYXIgPC0gYXMuaW50ZWdlcihzdHJfc3ViKGRhdGEyJERlYWxfRGF0ZSwtMikpDQoNCmNoYW5nZVkgPC0gZnVuY3Rpb24oeCl7DQogIGlmKHg8PTE4KXsNCiAgICB4ID0geCsyMDAwDQogIH0NCiAgZWxzZXsNCiAgICB4ID0geCsxOTAwDQogIH0NCiAgcmV0dXJuKHgpDQp9DQoNCmRhdGEyJFllYXIgPC0gc2FwcGx5KGRhdGEyJFllYXIsY2hhbmdlWSkNCmRhdGEyIDwtIGRhdGEyW3doaWNoKGRhdGEyJFllYXI+PTE5OTApLF0NCg0KI29ubHkgY29uc2lkZXIgZGVhbHMgdGhhdCBoYXZlIG5vbi1taXNzaW5nIGVudHJpZXMgZm9yICJQcmltYXJ5X0luZHVzdHJ5X1NlY3RvciINCmRhdGExIDwtIGRhdGExWyFpcy5uYShkYXRhMSRQcmltYXJ5X0luZHVzdHJ5X0NvZGUpLF0NCm5hbWVzKGRhdGEyKVsxXSA8LSAiRGVhbF9JZCINCmRhdGEyIDwtIGRhdGEyW3doaWNoKGRhdGEyJENvbXBhbnlJZCAlaW4lIGRhdGExJENvbXBhbnlJRCksXQ0KDQoNCiNmaWx0ZXIgaW52ZXN0b3IsIGRlYWwgYW5kIGNvbXBhbnkgcmVsYXRpb24gYmFzZWQgb24gYWJvdmUgc2VsZWN0aW9uDQpkYXRhNCA8LSBkYXRhNFt3aGljaChkYXRhNCREZWFsX0lkJWluJWRhdGEyJERlYWxfSWQpLF0NCm5hbWVzKGRhdGEzKVsxXSA8LSAiSW52ZXN0b3JfSWQiDQpkYXRhNCA8LSBkYXRhNFt3aGljaChkYXRhNCRJbnZlc3Rvcl9JZCVpbiVkYXRhMyRJbnZlc3Rvcl9JZCksXQ0KDQpgYGANCg0KDQojIFF1ZXN0aW9uIDENCg0KDQojIyBDb25zdHJ1Y3QgdGhlIHN0YXR1cyBtYXRyaXgNCg0KYWRkIGRlYWwgeWVhciBpbmZvcm1hdGlvbiB0byBpbnZlc3Rvci9kZWFsIGRhdGENCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI25vIG1pc3NpbmcgdmFsdWUgZm9yIGxlYWRfaW52ZXN0b3INCnVuaXF1ZShkYXRhNCRMZWFkX0ludmVzdG9yKQ0KDQojYWxsIHF1bGlmaWVkIGRlYWwNCmRhdGFjbGVhbiA8LSBtZXJnZShkYXRhNFssYygxLDIsNCldLGRhdGEyWyxjKDEsMzIpXSxieT0iRGVhbF9JZCIpIA0KDQpgYGANCg0KaW5jaWRlbmNlIG1hdHJpeA0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojb25seSBjb25zaWRlciBjby1pbnZlc3RtZW50DQpkMSA8LSBkYXRhY2xlYW4gJT4lDQogIGdyb3VwX2J5KERlYWxfSWQpICU+JQ0KICBzdW1tYXJpc2UoY291bnQ9bGVuZ3RoKHVuaXF1ZShJbnZlc3Rvcl9JZCkpKQ0KDQojI2ZpbmQgY28taW52ZXN0bWVudCBldmVudA0KZDIgPC0gZDFbd2hpY2goZDEkY291bnQ+MSksXQ0KDQojI2tlZXAgb25seSBkYXRhIGZvciBjby1pbnZlc3RtZW50DQpkMyA8LSBkYXRhY2xlYW5bd2hpY2goZGF0YWNsZWFuJERlYWxfSWQlaW4lZDIkRGVhbF9JZCksXQ0KDQojI25vdCBhbGwgY28taW52ZXN0bWVudCBldmVudHMgaGF2ZSBsZWFkIGludmVzdG9yDQp0MSA8LSBkMyAlPiUNCiAgZ3JvdXBfYnkoRGVhbF9JZCklPiUNCiAgc3VtbWFyaXNlKHN1bT1zdW0oTGVhZF9JbnZlc3RvcikpDQp0MiA8LSB0MVt3aGljaCh0MSRzdW0+MCksXQ0KDQp5ZWFybGlzdCA8LSBzb3J0KHVuaXF1ZShkMyRZZWFyKSkNCmBgYA0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI21ldGhvZDENCiN0cnkgdG8gc3RvcmUgYWRqIG1hdHJpeCBpbiBhIGxpc3QgYnV0IG1lbW9yeSBub3QgZW5vdWdoIGFuZCB0YWtlIHRvbyBsb25nIHRvIHJ1bg0KDQojY29uc3RydWN0IGluY2lkZW5jZSBtYXRyaXggZm9yIGNvLWludmVzdG1lbnRzIGFuZCB0cmFuc2Zvcm0gaXQgdG8gYWRqIG1hdHJpeCBieSB5ZWFyDQojc2hhcmVtdHgxIDwtIGxpc3QoKQ0KI2ZvcihpIGluIDE6bGVuZ3RoKHllYXJsaXN0KSl7DQojICB5ZWFyc2VsPC15ZWFybGlzdFtpXQ0KIyAgZzEgPC0gZDRbd2hpY2goZDQkWWVhcj09eWVhcnNlbCksXQ0KIyAgZzIgPC0gYXMubWF0cml4KGRhdGEuZnJhbWUoZGNhc3QoZzFbLGMoMSwyKV0sIEludmVzdG9yX0lkIH4gRGVhbF9JZCwgZnVuLmFnZ3JlZ2F0ZT1sZW5ndGgpLCByb3cubmFtZXMgPSAxKSkNCiMgIGczIDwtIGcyJSoldChnMikNCiMgIGRpYWcoZzMpIDwtIDANCiMgIHNoYXJlbXR4MVtbaV1dIDwtIGczDQojfQ0KDQojbWV0aG9kMg0KIzEuIGNvbnN0cnVjdCBpbmNpZGVuY2UgbWF0cml4IGZvciBjby1pbnZlc3RtZW50cw0KIzIuIHRyYW5zZm9ybSBpdCB0byBhZGogbWF0cml4IGJ5IHllYXINCiMzLiB0cmFuc2Zvcm0gaXQgdG8gZWRnZSBsaXN0IHdpdGggd2VpZ2h0IGFuZCB5ZWFyDQoNCiN1c2UgdGNyb3NzcHJvZCgpIGFuZCBzcGFyc2UgbWF0cml4IGZvciBmYXN0ZXIgbWF0cml4IG11bHRpcGxpY2F0aW9uIA0KDQpzaGFyZWVkZ2VsaXN0IDwtIGRhdGEudGFibGUoKQ0KZm9yKHllYXJzZWwgaW4geWVhcmxpc3Qpew0KICBnMSA8LSBkM1t3aGljaChkMyRZZWFyPT15ZWFyc2VsKSxdDQogIGcyIDwtIGFzLm1hdHJpeChkYXRhLmZyYW1lKGRjYXN0KGcxWyxjKDEsMildLCBJbnZlc3Rvcl9JZCB+IERlYWxfSWQsIGZ1bi5hZ2dyZWdhdGU9bGVuZ3RoKSwgcm93Lm5hbWVzID0gMSksc3BhcnNlID0gVFJVRSkNCiAgZzMgPC0gdGNyb3NzcHJvZChnMixnMikNCiAgZGlhZyhnMykgPC0gMA0KICBnNDwtIGdyYXBoLmFkamFjZW5jeShnMyx3ZWlnaHRlZD1UUlVFLG1vZGUgPSAidW5kaXJlY3RlZCIpDQogIHJlcyA8LSBnZXQuZGF0YS5mcmFtZShnNCkNCiAgcmVzJHllYXIgPC0geWVhcnNlbA0KICBzaGFyZWVkZ2VsaXN0IDwtIHJiaW5kKHNoYXJlZWRnZWxpc3QscmVzKQ0KfQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojZm9yIGVhY2ggeWVhciwgY29uc2lkZXIgcmVjZW50IDUgeWVhciBjby1pbnZlc3RtZW50IGNvdW50DQpzaGFyZWNvdW50IDwtIGRhdGEudGFibGUoKQ0KZm9yKHllYXJzZWwgaW4geWVhcmxpc3Qpew0KICBnMSA8LSBzaGFyZWVkZ2VsaXN0W3doaWNoKChzaGFyZWVkZ2VsaXN0JHllYXI8PXllYXJzZWwpJihzaGFyZWVkZ2VsaXN0JHllYXI+eWVhcnNlbC01KSksXSAlPiUNCiAgICBncm91cF9ieShmcm9tLHRvKSAlPiUNCiAgICBzdW1tYXJpc2UoeWVhcj15ZWFyc2VsLGNvdW50PXN1bSh3ZWlnaHQpKQ0KICBzaGFyZWNvdW50IDwtIHJiaW5kKHNoYXJlY291bnQsYXMuZGF0YS5mcmFtZShnMSkpDQp9DQojd3JpdGUuY3N2KHNoYXJlY291bnQsInNoYXJlY291bnQuY3N2IikNCmBgYA0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI2xlYWQgaW52ZXN0bWVudA0KbGVhZGVkZ2VsaXN0IDwtIGRhdGEudGFibGUoKQ0KZDQgPC0gZDNbd2hpY2goZDMkRGVhbF9JZCVpbiV0MiREZWFsX0lkKSxdDQpjb2ludmVzdGxpc3QgPC0gdW5pcXVlKGQ0JERlYWxfSWQpDQpgYGANCg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmZvcihkZWFsc2VsIGluIGNvaW52ZXN0bGlzdCl7DQogIGcxIDwtIGQ0W3doaWNoKGQ0JERlYWxfSWQ9PWRlYWxzZWwpLF0NCiAgZzIgPC0gZXhwYW5kLmdyaWQodW5saXN0KGcxW3doaWNoKGcxJExlYWRfSW52ZXN0b3I9PTEpLDJdKSx1bmxpc3QoZzFbLDJdKSkNCiAgZzIkeWVhciA8LSBnMSRZZWFyDQogIGxlYWRlZGdlbGlzdCA8LSByYmluZChsZWFkZWRnZWxpc3QsZzIpDQp9DQpgYGANCg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNvbG5hbWVzKGxlYWRlZGdlbGlzdCkgPC0gYygibGVhZCIsIm5vbiIsInllYXIiKQ0KI3dyaXRlLmNzdihsZWFkZWRnZWxpc3QsImxlYWRlZGdlbGlzdC5jc3YiKQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojZm9yIGVhY2ggeWVhciwgY29uc2lkZXIgcmVjZW50IDUgeWVhciBjby1pbnZlc3RtZW50IGxlYWQgY291bnQNCmxlYWRjb3VudCA8LSBkYXRhLnRhYmxlKCkNCmZvcih5ZWFyc2VsIGluIHllYXJsaXN0KXsNCiAgZzEgPC0gbGVhZGVkZ2VsaXN0W3doaWNoKChsZWFkZWRnZWxpc3QkeWVhcjw9eWVhcnNlbCkmKGxlYWRlZGdlbGlzdCR5ZWFyPnllYXJzZWwtNSkpLF0gJT4lDQogICAgZ3JvdXBfYnkobGVhZCxub24pICU+JQ0KICAgIHN1bW1hcmlzZSh5ZWFyPXllYXJzZWwsY291bnQ9bigpKQ0KICBsZWFkY291bnQgPC0gcmJpbmQobGVhZGNvdW50LGFzLmRhdGEuZnJhbWUoZzEpKQ0KfQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojYWRqdXN0IGRhdGEgdHlwZQ0KbGVhZGNvdW50JGxlYWQgPC0gYXMuY2hhcmFjdGVyKGxlYWRjb3VudCRsZWFkKQ0KbGVhZGNvdW50JG5vbiA8LSBhcy5jaGFyYWN0ZXIobGVhZGNvdW50JG5vbikNCg0KI21ha2Ugc3VyZSB0byBoYXZlIHRoZSBkaWEgdmFsdWUgZXF1YWwgdG8gMA0KbGVhZGNvdW50IDwtIGxlYWRjb3VudFt3aGljaChsZWFkY291bnQkbGVhZCE9bGVhZGNvdW50JG5vbiksXQ0KY29sbmFtZXMobGVhZGNvdW50KSA8LSBjKCJsZWFkIiwibm9uIiwieWVhciIsImxlYWRzaGFyZSIpDQoNCiN3cml0ZS5jc3YobGVhZGNvdW50LCJsZWFkY291bnQuY3N2IikNCmBgYA0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI2NvbnN0cnVjdCB3aG9sZSBzaGFyZWNvdW50IGxpc3QNCiNoYXZlIHYxIC0+IHYyIGFuZCB2MiAtPiB2MQ0Kc2hhcmVjb3VudCA8LSBzaGFyZWNvdW50W3doaWNoKHNoYXJlY291bnQkZnJvbSE9c2hhcmVjb3VudCR0byksXQ0Kc2hhcmVjb3VudDEgPC0gY2JpbmQoc2hhcmVjb3VudFssMl0sc2hhcmVjb3VudFssMV0sc2hhcmVjb3VudFssYygzLDQpXSkNCmNvbG5hbWVzKHNoYXJlY291bnQxKSA8LSBjKCJmcm9tIiwidG8iLCJ5ZWFyIiwiY291bnQiKQ0Kc2hhcmVjb3VudCA8LSByYmluZChzaGFyZWNvdW50LHNoYXJlY291bnQxKQ0KY29sbmFtZXMoc2hhcmVjb3VudCkgPC0gYygibGVhZCIsIm5vbiIsInllYXIiLCJjb3VudHNoYXJlIikNCg0KI2NvbWJpbmUgc2hhcmUgYW5kIGNvLWludmVzdG1lbnQgaW5mb3JtYXRpb24NCnN0YXR1cyA8LSBtZXJnZShzaGFyZWNvdW50LGxlYWRjb3VudCxieT1jKCJsZWFkIiwibm9uIiwieWVhciIpLGFsbC54ID0gVFJVRSkNCnN0YXR1c1t3aGljaChpcy5uYShzdGF0dXMkbGVhZHNoYXJlKSksNV0gPC0gMA0KDQojYXMgZGVmaW5hdGlvbiANCnN0YXR1cyR2YWx1ZSA8LSBzdGF0dXMkbGVhZHNoYXJlL3N0YXR1cyRjb3VudHNoYXJlDQpzdGF0dXMxIDwtIHN0YXR1c1ssYygxLDIsMyw1KV0NCmNvbG5hbWVzKHN0YXR1czEpWzRdPC0id2VpZ2h0Ig0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojZ2V0IGVpaWdlbnZlY3RvciBjZW50cmFsaXR5IG9mIHRoZSBtYXRyaXggYXMgc3RhdHVzDQpzdGF0dXMyIDwtIGRhdGEudGFibGUoKQ0KZm9yKHllYXJzZWwgaW4geWVhcmxpc3Qpew0KICBnMSA8LSBzdGF0dXMxW3doaWNoKHN0YXR1czEkeWVhcj09eWVhcnNlbCksYygxLDIsNCldDQogIGcyIDwtIGdyYXBoLmRhdGEuZnJhbWUoZzEsZGlyZWN0ZWQ9VFJVRSkNCiAgZzMgPC0gZWlnZW5fY2VudHJhbGl0eShnMiwgZGlyZWN0ZWQgPSBUUlVFLCB3ZWlnaHRzID0gTlVMTCkkdmVjdG9yDQogIGc0IDwtIGFzLmRhdGEudGFibGUoY2JpbmQobmFtZXMoZzMpLHVubmFtZShnMykpKQ0KICBnNCR5ZWFyIDwtIHllYXJzZWwNCiAgc3RhdHVzMiA8LSByYmluZChzdGF0dXMyLGc0KQ0KfQ0KDQojd3JpdGUuY3N2KHN0YXR1czIsInN0YXR1czIuY3N2IikNCg0KYGBgDQoNCmBgYHtyfQ0Kc3RhdHVzMiA8LSBmcmVhZCgic3RhdHVzMi5jc3YiLGhlYWRlciA9IFRSVUUpWyxjKDI6NCldDQpgYGANCg0KIyBRdWVzdGlvbjFBDQpUcmFkaXRpb25hbGx5LCB2ZW50dXJlIGNhcGl0YWwgYW5hbHlzaXMgaGF2ZSBvbmx5IGNvbnNpZGVyZWQgdGhlIGNvbmNlbnRyYXRpb24gb2YgYSB2ZW50dXJlIGNhcGl0YWwgZmlybXMgaW52ZXN0bWVudHMgaW4gdG8gZGlmZmVyZW50IHBvcnRmb2xpbyBjYXRlZ29yaWVzLiBUaGUgbW9yZSBjb25jZW50cmF0ZWQgYSBmaXJtJ3MgaW52ZXN0bWVudHMsIHRoZSBsZXNzIGRpdmVyc2lmaWVkIGl0IGlzLiANCg0KIyMjIGNhbGN1bGF0ZSBIZXJmaW5kYWhsIGluZGV4IA0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojdW5pcXVlIGNhdGVnb3J5DQpjYXRlZ29yeWxpc3QgPC0gdW5pcXVlKGRhdGExJFByaW1hcnlfSW5kdXN0cnlfQ29kZSkNCg0KI2xvYWQgbHBhY2thZ2UgaGhpIGZvciBoZXJmaW5kYWhsIGluZGV4IGNhbGN1bGF0aW9uDQpsaWJyYXJ5KCJoaGkiKQ0KDQojY29tYmluZSB3aG9sZSBxdWFsaWZpZWQgZGVhbCBkYXRhIGFuZCBjb21wYW55IHR5cGUgZGF0YQ0KZGF0YTUgPC0gbWVyZ2UoZGF0YWNsZWFuLGRhdGEyWyxjKDEsMildLGJ5PSJEZWFsX0lkIixhbGwueCA9IFRSVUUpDQpjb2xuYW1lcyhkYXRhNSlbNV08LSJDb21wYW55SUQiDQpkYXRhNSA8LSBtZXJnZShkYXRhNSxkYXRhMVssYygxLDgpXSxieT0iQ29tcGFueUlEIixhbGwueCA9IFRSVUUpDQoNCiNncm91cCBieSBlYWNoIHllYXIvZmlybSBmb3IgcGVyY2VudGFnZSBvZiBlYWNoIHNlY3Rvcg0KZGF0YTYgPC0gZGF0YTUgJT4lDQogIGdyb3VwX2J5KEludmVzdG9yX0lkLFllYXIsUHJpbWFyeV9JbmR1c3RyeV9Db2RlKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50PW4oKSklPiUNCiAgZ3JvdXBfYnkoSW52ZXN0b3JfSWQsWWVhcikgJT4lIA0KICBtdXRhdGUoUGVyY2VudGFnZT1jb3VudC9zdW0oY291bnQpKjEwMCkNCg0KI3RhYmxlIGNvbmNlbnRyYXRpb24gdG8gc3RvcmUgaGVyZmluZGFobCBpbmRleA0KY29uY2VudHJhdGlvbiA8LSB1bmlxdWUoZGF0YTZbLGMoMSwyKV0pDQpjb25jZW50cmF0aW9uJGNvbiA8LSBOQQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojZ2V0IGNvbmNlbnRyYXRpb24NCmZvcihpIGluICgxOmRpbShjb25jZW50cmF0aW9uKVsxXSkpew0KICBnMSA8LSBkYXRhNlsod2hpY2goKGRhdGE2JEludmVzdG9yX0lkPT1jb25jZW50cmF0aW9uW2ksXSRJbnZlc3Rvcl9JZCkmKGRhdGE2JFllYXI9PWNvbmNlbnRyYXRpb25baSxdJFllYXIpKSksYygzLDUpXQ0KICBnMiA8LSBoaGkoYXMuZGF0YS5mcmFtZShnMSksIlBlcmNlbnRhZ2UiKQ0KICBjb25jZW50cmF0aW9uW2ksM10gPC0gZzINCn0NCg0KI3dyaXRlLmNzdihjb25jZW50cmF0aW9uLCJjb25jZW50cmF0aW9uLmNzdiIpDQpgYGANCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojaW1wb3J0IHNhdmVkIGRhdGEgZnJvbSBhYm92ZSBjb2RlDQpjb25jZW50cmF0aW9uIDwtIGZyZWFkKCJjb25jZW50cmF0aW9uLmNzdiIsIGhlYWRlciA9IFRSVUUpWyxjKDI6NCldDQpgYGANCg0KDQpjb250cm9sIHZhcmlhYmxlIDENCndoZXRoZXIgYSB2ZW50dXJlIGNhcGl0YWwgZmlybSB0ZW5kcyB0byBvcmlnaW5hdGUgaXRzIG93biBkZWFsczogZm9yIG1vcmUgdGhhbiA1MCUgb2YgdGhlIGNvbXBhbmllcyBpdCBpbnZlc3RzIGluLCBpdCBpbnZlc3RzIGluIHRoZSBmaXJzdCBpbnZlc3RtZW50IHJvdW5kIHRoaXMgY29tcGFueSBoYXMgcmVjZWl2ZWQgDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdGFjMSA8LSBkYXRhNQ0KZGF0YWMxWywgZmlyc3Rfcm91bmQgOj0gaWZlbHNlKFllYXI9PW1pbihZZWFyKSwxLDApLCBieT1saXN0KENvbXBhbnlJRCldDQoNCiNncm91cCBieSBlYWNoIHllYXIvZmlybSBmb3IgbnVtYmVyIG9mIHRvdGFsIGludmVzdG1lbnQgYW5kIGlmIGZpcnN0X3JvdW5kDQpkYXRhYzFyIDwtIGRhdGFjMSAlPiUNCiAgZ3JvdXBfYnkoSW52ZXN0b3JfSWQsWWVhcikgJT4lDQogIHN1bW1hcmlzZSh5ZWFyaW52ZXN0bWVudD1uKCkseWVhcmZpcnN0PXN1bShmaXJzdF9yb3VuZCkpJT4lDQogIGdyb3VwX2J5KEludmVzdG9yX0lkKSAlPiUNCiAgbXV0YXRlKHRvdGFsPWN1bXN1bSh5ZWFyaW52ZXN0bWVudCksdG90YWxmaXJzdD1jdW1zdW0oeWVhcmZpcnN0KSkNCmRhdGFjMXIgPC0gYXMuZGF0YS50YWJsZShkYXRhYzFyKQ0KDQojaWYgbW9yZSB0aGFuIDUwJSBhcmUgaW4gdGhlIGZpcnN0IGludmVzdG1lbnQgcm91bmQNCmRhdGFjMXJbLGZpcnN0X3JvdW5kIDo9IGlmZWxzZSh0b3RhbGZpcnN0L3RvdGFsPjAuNSwxLDApXQ0KDQoNCmBgYA0KDQoNCmNvbnRyb2wgdmFyaWFibGUgMg0Kd2hldGhlciBhIHZlbnR1cmUgY2FwaXRhbCA/Pz9ybSB0ZW5kcyB0byBpbnZlc3QgaW4gdGhlIElUIHNlY3RvcjogbW9yZSB0aGFuIDUwJSBvZiB0aGUgY29tcGFuaWVzIGl0IGludmVzdHMgaW4gYXJlIGluIHRoZSBjb21wYW55LWxldmVsIHZhcmlhYmxlIFByaW1hcnkgSW5kdXN0cnkgU2VjdG9yICJJbmZvcm1hdGlvbiBUZWNobm9sb2d5Ig0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRhYzIgPC0gZGF0YTUNCmRhdGFjMiA8LSBtZXJnZShkYXRhYzIsZGF0YTFbLGMoMSw2KV0sYnk9IkNvbXBhbnlJRCIsYWxsLnggPSBUUlVFKQ0KZGF0YWMyWywgSVQgOj0gaWZlbHNlKFByaW1hcnlfSW5kdXN0cnlfU2VjdG9yPT0iSW5mb3JtYXRpb24gVGVjaG5vbG9neSIsMSwwKV0NCg0KI2dyb3VwIGJ5IGVhY2ggeWVhci9maXJtIGZvciBudW1iZXIgb2YgdG90YWwgaW52ZXN0bWVudCBhbmQgaWYgSVQNCmRhdGFjMnIgPC0gZGF0YWMyICU+JQ0KICBncm91cF9ieShJbnZlc3Rvcl9JZCxZZWFyKSAlPiUNCiAgc3VtbWFyaXNlKHllYXJpbnZlc3RtZW50PW4oKSx5ZWFyaXQ9c3VtKElUKSklPiUNCiAgZ3JvdXBfYnkoSW52ZXN0b3JfSWQpICU+JQ0KICBtdXRhdGUodG90YWw9Y3Vtc3VtKHllYXJpbnZlc3RtZW50KSx0b3RhbGl0PWN1bXN1bSh5ZWFyaXQpKQ0KZGF0YWMyciA8LSBhcy5kYXRhLnRhYmxlKGRhdGFjMnIpDQoNCiNpZiBtb3JlIHRoYW4gNTAlIGFyZSBpbiBJVCBzZWN0b3INCmRhdGFjMnJbLElUIDo9IGlmZWxzZSh0b3RhbGl0L3RvdGFsPjAuNSwxLDApXQ0KDQoNCmBgYA0KDQoNCmNvbnRyb2wgdmFyaWFibGUgMw0Kd2hldGhlciBhIHZlbnR1cmUgY2FwaXRhbCBmaXJtIHRlbmRzIHRvIGludmVzdCBpbiBlYXJseS1zdGFnZSBzdGFydHVwczogbW9yZSB0aGFuIDUwJSBvZiB0aGUgY29tcGFuaWVzIGl0IGludmVzdHMgaW4gYXJlIG9mIHRoZSBEZWFsIFR5cGUgMSAiRWFybHkgU3RhZ2UgVkMiLCAiQWNjZWxlcmF0b3IvSW5jdWJhdG9yIiwgIlNlZWQgUm91bmQiLCBvciAiQW5nZWwgKGluZGl2aWR1YWwpIg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRhYzMgPC0gZGF0YTUNCmRhdGFjMyA8LSBtZXJnZShkYXRhYzMsZGF0YTJbLGMoMSw5KV0sYnk9IkRlYWxfSWQiLGFsbC54ID0gVFJVRSkNCmRhdGFjM1ssIHR5cGUgOj0gaWZlbHNlKERlYWxfVHlwZV8xPT0iRWFybHkgU3RhZ2UgVkMifERlYWxfVHlwZV8xPT0iQWNjZWxlcmF0b3IvSW5jdWJhdG9yInxEZWFsX1R5cGVfMT09IlNlZWQgUm91bmQifERlYWxfVHlwZV8xPT0iQW5nZWwgKGluZGl2aWR1YWwpIiwxLDApXQ0KDQojZ3JvdXAgYnkgZWFjaCB5ZWFyL2Zpcm0gZm9yIG51bWJlciBvZiB0b3RhbCBpbnZlc3RtZW50IGFuZCBpZiBzcGVjaWZpYyB0eXBlcw0KZGF0YWMzciA8LSBkYXRhYzMgJT4lDQogIGdyb3VwX2J5KEludmVzdG9yX0lkLFllYXIpICU+JQ0KICBzdW1tYXJpc2UoeWVhcmludmVzdG1lbnQ9bigpLHllYXJ0eXBlPXN1bSh0eXBlKSklPiUNCiAgZ3JvdXBfYnkoSW52ZXN0b3JfSWQpICU+JQ0KICBtdXRhdGUodG90YWw9Y3Vtc3VtKHllYXJpbnZlc3RtZW50KSx0b3RhbHR5cGU9Y3Vtc3VtKHllYXJ0eXBlKSkNCmRhdGFjM3IgPC0gYXMuZGF0YS50YWJsZShkYXRhYzNyKQ0KDQojaWYgbW9yZSB0aGFuIDUwJSBhcmUgaW4gZWFybHkgc3RhZ2Ugc3RhcnR1cHMNCmRhdGFjM3JbLGVhcmx5IDo9IGlmZWxzZSh0b3RhbHR5cGUvdG90YWw+MC41LDEsMCldDQpgYGANCg0KDQptZXJnZSByZWdyZXNzaW9uIGRhdGEgdG9nZXRoZXINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KcTFhIDwtIG1lcmdlKGRhdGFjMXIsZGF0YWMycixieT1jKCJJbnZlc3Rvcl9JZCIsIlllYXIiKSkNCnExYSA8LSBtZXJnZShxMWEsZGF0YWMzcixieT1jKCJJbnZlc3Rvcl9JZCIsIlllYXIiKSkNCnExYSA8LSBxMWFbLGMoMSwyLDcsMTIsMTcpXQ0KY29sbmFtZXMoc3RhdHVzMikgPC0gYygiSW52ZXN0b3JfSWQiLCJzY29yZSIsIlllYXIiKQ0KcTFhIDwtIG1lcmdlKHExYSxzdGF0dXMyLGJ5PWMoIkludmVzdG9yX0lkIiwiWWVhciIpKQ0KcTFhIDwtIG1lcmdlKHExYSxjb25jZW50cmF0aW9uLGJ5PWMoIkludmVzdG9yX0lkIiwiWWVhciIpKQ0KDQpgYGANCg0KZ2V0IGxhZyB2YWx1ZSBmb3IgY29udHJvbCB2YXJpYWJsZXMgYW5kIHN0YXR1cyB2YXJpYWJsZQ0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpxMWEkc2NvcmUgPC0gYXMubnVtZXJpYyhxMWEkc2NvcmUpDQpxMWEgPC0gDQogICAgcTFhICU+JQ0KICAgIGdyb3VwX2J5KEludmVzdG9yX0lkKSAlPiUNCiAgICBtdXRhdGUobGFnX3N0YXR1cyA9IGRwbHlyOjpsYWcoc2NvcmUsIG4gPSAxLCBkZWZhdWx0ID0gTkEpLGxhZ19lYXJseSA9IGRwbHlyOjpsYWcoZWFybHksIG4gPSAxLCBkZWZhdWx0ID0gTkEpLA0KICAgICAgICAgICBsYWdfSVQgPSBkcGx5cjo6bGFnKElULCBuID0gMSwgZGVmYXVsdCA9IE5BKSxsYWdfZmlyc3QgPSBkcGx5cjo6bGFnKGZpcnN0X3JvdW5kLCBuID0gMSwgZGVmYXVsdCA9IE5BKSkNCg0KcTFhcmVnIDwtIHExYVssYygxLDIsNzoxMSldDQoNCnExYXJlZzEgPC0gYXMuZGF0YS50YWJsZShuYS5vbWl0KHExYXJlZykpDQoNCg0KYGBgDQoNCg0KDQpyZWdyZXNzaW9uDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnN1bW1hcnkocGxtKGNvbiB+IGxhZ19zdGF0dXMgKyBJKGxhZ19zdGF0dXNeMikrIGxhZ19maXJzdCArIGxhZ19JVCArIGxhZ19lYXJseSArIFllYXIsIHExYXJlZzEsIGVmZmVjdCA9ICJpbmRpdmlkdWFsIiwgbW9kZWwgPSAid2l0aGluIiwgaW5kZXggPSAiSW52ZXN0b3JfSWQiKSkNCg0KYGBgDQoNCg0KIyMjIElOU0lHSFQgDQoNCldoYXQgaXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHN0YXR1cyBhbmQgZGl2ZXJzaWZpY2F0aW9uPw0KDQpBY2NvcmRpbmcgdG8gYWJvdmUgcmVncmVzc2lvbiwgbGFnX3N0YXR1cyBoYXMgbmVnYXRpdmUgZWZmZWN0IGFuZCB0aGUgc3F1YXJlIG9mIGxhZ19zdGF0dXMgaGFzIHBvc2l0aXZlIGVmZmVjdCBvbiB0aGUgY29uY2VudHJhdGlvbiBsZXZlbCBvZiB0aGUgaW52ZXN0bWVudHMgb2YgYSB2ZW50dXJlIGNhcGl0YWwgYXQgdGhlIGNvbmZpZGVuY2UgbGV2ZWwgb2YgMCB3aGljaCBpcyBoaWdobHkgc2lnbmlmaWNhbnQuDQpJdCBzdWdnZXN0cyB0aGF0IGF0IGZpcnN0LCB0aGUgaW5jcmVhc2Ugb2YgYSBmaXJtJ3Mgc3RhdHVzIGNvbnRyaWJ1dGVzIHRvIHRoZSBkaXZlcnNpZmljYXRpb24gb2YgaXRzIGludmVzdG1lbnRzLCBidXQgd2hlbiB0aGUgc3RhdHVzIHJlYWNoIGEgY2VydGFpbiBsZXZlbCwgdGhlIGluY3JlYXNlIG9mIGEgZmlybSdzIHN0YXR1cyB0ZW5kcyB0byBsb3dlciB0aGUgZGl2ZXJzaWZpY2F0aW9uIG9mIHRoZSBmaXJtJ3MgaW52ZXN0bWVudHMuDQoNClRha2UgY29udHJvbCB2YXJpYWJsZXMgaW50byBhY2NvdW50LCBib3RoIGZpcnN0X3JvdW5kIGFuZCBlYXJseV9zdGFnZSBzaG93IHNpZ25pZmljYW50IG5lZ3RpdmUgZWZmZWN0IG9uIHRoZSBjb25jZW50cmF0aW9uIGxldmVsLiBXZSBjYW4gY29uY2x1ZGUgdGhhdCB3aXRoIHNhbWUgc3RhdHVzIGluIHRoZSBwcmV2aW91cyB5ZWFyLCBhIGZpcm0gdGhhdCB0ZW5kcyB0byBvcmlnaW5hdGUgaXRzIG93biBkZWFscyBvciB0ZW5kcyB0byBpbnZlc3QgaW4gZWFybHktc3RhZ2Ugc3RhcnR1cHMgaXMgbW9yZSBsaWtlbHkgdG8gaGF2ZSBtb3JlIGRpdmVyc2lmaWVkIGludmVzdG1lbnQgcHJvZmlsZSBpbiB0aGlzIHllYXIuDQoNCg0KIyBRdWVzdGlvbiAxYg0KDQpDcmVhdGUgYSBuZXcgbWVhc3VyZSBvZiBkaXZlcnNpPz8/Y2F0aW9uIHRoYXQgdGFrZXMgdGhlIHJlbGF0ZWRuZXNzIG9mIGluZHVzdHJ5IGNhdGVnb3JpZXMgaW50byBhY2NvdW50LiBGaXJzdCBjb21wdXRlIHRoZSByZWxhdGVkbmVzcyBvZiBlYWNoIGluZHVzdHJ5IGNhdGVnb3J5IGFzIHRoZSBKYWNjYXJkIGRpc3RhbmNlIGJldHdlZW4gZWFjaCBwYWlyIG9mIGluZHVzdHJ5IGNhdGVnb3JpZXMgZm9yIGVhY2ggeWVhciwgdXNpbmcgdGhlIGNvbXBhbnktbGV2ZWwgdmFyaWFibGUgIlByaW1hcnkgSW5kdXN0cnkgQ29kZSIuIEJhc2UgdGhlIHNpbWlsYXJpdHkgb24gdGhlIGNvLW9jY3VycmVuY2Ugb2YgaW5kdXN0cnkgY2F0ZWdvcmllcyBpbiBpbnZlc3RvcnMnIHBvcnRmb2xpb3MgY3VtdWxhdGl2ZSB0byB0aGUgY3VycmVudCB5ZWFyLg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNuZXcgdGFibGUgdG8gc3RvcmUgbmljaGVfd2lkdGggdmFsdWUgZm9yIGVhY2ggeWVhciBlYWNoIGZpcm0NCm5pY2hlX3dpZHRoIDwtIGRhdGEudGFibGUoKQ0KDQpgYGANCg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdGExYiA8LSBkYXRhNVssYygzLDUsNildDQoNCiNnZXQgcmVsYXRlZG5lc3MgZWFjaCBpbmR1c3RyeSBjYXRlZ29yeSBhcyB0aGUgamFjYXJkIGRpc3RhbmNlIGJldHdlZW4gZWFjaCBwYWlyIG9mIGluZHVzdHJ5IGNhdGVnb3JpZXMgZm9yIGVhY2ggeWVhcg0KZm9yKHllYXJzZWwgaW4geWVhcmxpc3Qpew0KICBzdWJwYWlyIDwtIGRhdGExYltkYXRhMWIkWWVhcjw9eWVhcnNlbCxjKDEsMyldDQogIGcxIDwtIGRhdGEuZnJhbWUoZGNhc3Qoc3VicGFpciwgUHJpbWFyeV9JbmR1c3RyeV9Db2RlIH4gSW52ZXN0b3JfSWQsZnVuLmFnZ3JlZ2F0ZT1sZW5ndGgpLCByb3cubmFtZXMgPSAxKQ0KICBnMVtnMT4xXSA8LSAxDQogICNnZXQgZGlzdCBtYXRyaXgNCiAgZzIgPC0gYXMubWF0cml4KGRpc3QoZzEpKQ0KICANCiAgI2dldCBpbmR1c3RyeSBjb21iaW5hdGlvbiBmb3IgZWFjaCBpbnZlc3RvciANCiAgc3ViaW4gPC0gdW5pcXVlKHN1YnBhaXIpDQogIA0KIA0KICBzdWJpblssIGluZGNvdW50IDo9IC5OICwgYnkgPSdJbnZlc3Rvcl9JZCddDQogIA0KICAjZ2V0IHRvdGFsIGluZHVzdHJ5DQogIHJlczEgPC0gdW5pcXVlKHN1YmluWyxjKDEsMyldKQ0KICANCiAgI29ubHkgY29uc2lkZXIgaW52ZXN0b3JzIHRoYXQgaGF2ZSBpbnZlc3RlZCBpbiBtb3JlIHRoYW4gb25lIHR5cGUgb2YgaW5kdXN0cmllcw0KICBzdWJpbjEgPSBzdWJpbltpbmRjb3VudD4xXQ0KICANCiAgI2NvbWJpbmF0aW9uDQogIGNvbWI8LSBzdWJpbjFbLGFzLmRhdGEudGFibGUodChjb21ibihQcmltYXJ5X0luZHVzdHJ5X0NvZGUsMikpKSwgYnk9J0ludmVzdG9yX0lkJ10NCiAgY29tYjwtIGFzLmRhdGEuZnJhbWUoY29tYikNCiAgY29tYiA8LWNvbWJbY29tcGxldGUuY2FzZXMoY29tYiksIF0NCiAgY29tYiA8LSBjb21iWyEoKGNvbWIkVjE9PSIiKSB8IGNvbWIkVjI9PSIiKSwgXQ0KICANCiAgZm9yKGkgaW4gKDE6bnJvdyhjb21iKSkpew0KICAgIGNvbWJbaSwnZGlzdGFuY2UnXTwtIGcyW2NvbWJbaSwyXSxjb21iW2ksM11dDQogIH0NCiAgDQogICNzdW0gZGlzdGFuY2UNCiAgcmVzIDwtIGNvbWIgJT4lDQogICAgZ3JvdXBfYnkoSW52ZXN0b3JfSWQpJT4lDQogICAgc3VtbWFyaXNlKHN1bV9kaXN0PXN1bShkaXN0YW5jZSkpDQogIHJlc3cgPC0gbWVyZ2UocmVzMSxyZXMsYnk9IkludmVzdG9yX0lkIixhbGwueCA9IFRSVUUpDQogIHJlc3ckWWVhciA8LSB5ZWFyc2VsDQogIG5pY2hlX3dpZHRoIDwtIHJiaW5kKG5pY2hlX3dpZHRoLHJlc3cpDQogIA0KfQ0KDQojd3JpdGUuY3N2KG5pY2hlX3dpZHRoLCJuaWNoZV93aWR0aC5jc3YiKQ0KDQpgYGANCg0KYGBge3J9DQojbmljaGVfd2lkdGggPC0gZnJlYWQoIm5pY2hlX3dpZHRoLmNzdiIsaGVhZGVyPVRSVUUpWyxjKDI6NSldDQpgYGANCg0KDQpyZWdyZXNzaW9uDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbmljaGVfd2lkdGgkbncgPC0gMS0oMS8oMStuaWNoZV93aWR0aCRzdW1fZGlzdC8obmljaGVfd2lkdGgkaW5kY291bnQtMSkpKQ0KbmljaGVfd2lkdGggPC0gYXMuZGF0YS50YWJsZShuaWNoZV93aWR0aCkNCg0KI0lmIGFuIGludmVzdG9yIG9ubHkgaW52ZXN0cyBpbiBhIHNpbmdsZSBpbmR1c3RyeSBjYXRlZ29yeSwgc2V0IHRoZSBuaWNoZV93aWR0aCBlcXVhbCB0byAwDQpuaWNoZV93aWR0aFt3aGljaChpcy5uYShuaWNoZV93aWR0aCRudykpLDVdPC0wDQoNCg0KcTFiIDwtIG1lcmdlKHExYSxuaWNoZV93aWR0aFssYygxLDQsNSldLGJ5PWMoIkludmVzdG9yX0lkIiwiWWVhciIpKQ0KcTFiIDwtIGFzLmRhdGEudGFibGUocTFiKQ0KDQojVGhlIGFwcHJvYWNoIGZvciBpbmNvcnBvcmF0aW5nIGZpeGVkIGVmZmVjdHMgZm9yIHRoaXMgbW9kZWwgaXMgZGlmZmVyZW50OiBpbmNsdWRlIGluIHRoZSBtb2RlbCB0aGUgYXZlcmFnZSB2YWx1ZXMgZm9yIGFsbCBvZiB0aGUgcHJlZGljdG9ycywgZXhjZXB0IGZvciB0aGUgeWVhciwgZm9yIGVhY2ggZmlybSBvdmVyIGl0c2xpZmV0aW1lLg0KcTFiWyxhdmdfc3RhdHVzOj0gbWVhbihzY29yZSxuYS5ybT1UUlVFKSwgYnk9SW52ZXN0b3JfSWRdDQpxMWJbLGF2Z19zdGF0dXNfc3F1YXJlZCA6PSBtZWFuKHNjb3JlXjIsbmEucm09VFJVRSksIGJ5PUludmVzdG9yX0lkXQ0KcTFiWyxhdmdfRmlyc3RfUm91bmQ6PSBtZWFuKGZpcnN0X3JvdW5kLG5hLnJtPVRSVUUpLCBieT1JbnZlc3Rvcl9JZF0NCnExYlssYXZnX0lUX1NlY3Rvcjo9IG1lYW4oSVQsbmEucm09VFJVRSksIGJ5PUludmVzdG9yX0lkXQ0KcTFiWyxhdmdfRWFybHlfU3RhZ2U6PSBtZWFuKGVhcmx5LG5hLnJtPVRSVUUpLCBieT1JbnZlc3Rvcl9JZF0NCg0KI3JlZ3Jlc3Npb24NCnN1bW1hcnkoZ2xtKG53IH4gbGFnX3N0YXR1cyArIEkobGFnX3N0YXR1c14yKSsgbGFnX2ZpcnN0ICsgbGFnX0lUICsgbGFnX2Vhcmx5ICsgYXZnX3N0YXR1cyArIGF2Z19zdGF0dXNfc3F1YXJlZCthdmdfRmlyc3RfUm91bmQgKyBhdmdfSVRfU2VjdG9yICsgYXZnX0Vhcmx5X1N0YWdlICsgWWVhciwgcTFiLCBmYW1pbHkgPSBxdWFzaWJpbm9taWFsKGxpbmsgPSAibG9naXQiKSkpDQoNCg0KDQpgYGANCg0KIyMgSU5TSUdIVA0KDQpXaGF0IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBzdGF0dXMgYW5kIGRpdmVyc2lmaWNhdGlvbj8NCg0KQWNjb3JkaW5nIHRvIGFib3ZlIHJlZ3Jlc3Npb24gcmVzdWx0LCB0aGUgbGFnIHZhbHVlIG9mIHN0YXR1cyBoYXZlIHBvc2l0aXZlIGVmZmVjdCBhbmQgaXQncyBzcXVhcmUgdGVybSBoYXZlIG5lZ2F0aXZlIGVmZmVjdCBvbiB0aGUgbGV2ZWwgb2YgZGljZXJzaWZpY2F0aW9uIG9mIGEgZmlybSdzIGludmVzdG1lbnRzIHdpdGggc2lnbmlmaWNhbnQgb24gMCBjb25maWRlbmNlIGxldmVsLiBJdCBzdWdnZXN0cyB0aGF0IHZlbnR1cmUgY2FwaXRhbCB3aXRoIGhpZ2ggYW5kIGxvdyBzdGF0dXMgYm90aCBoYXZlIGxvd2VyIGRpdmVyc2lmaWNhdGlvbiBsZXZlbCBpbiB0aGVpciBpbnZlc3RtZW50IHByb2ZvbGlvIHdoaWxlIG1pZGRsZSBzdGF0dXMgdmVudHVyZSBjYXBpdGFsIHRlbmRzIHRvIGhhdmUgaGlnaGVyIGRpdmVyc2lmaWNhdGlvbiBsZXZlbCBpbiB0aGVpciBpbnZlc3RtZW50IHByb2ZvbGlvLg0KDQpUYWtlIGNvbnRyb2wgdmFyaWFibGUgaW50byBhY2NvdW50LCB0aGUgbGFnIHZhbHVlIG9mIGEgZmlybSdzIHRlbmRlbmN5IG9mIGludmVzdGluZyBpbiBmaXJzdCByb3VuZCBhbmQgZWFybHkgc3RhZ2Ugc2hvdyBuZWdhdGl2ZSBlZmZlY3Qgd2l0aCBzaWduaWZpY2FuY2UuIFdlIGNhbiBjb25jbHVkZSB0aGF0IHdpdGggc2FtZSBzdGF0dXMgaW4gdGhlIHByZXZpb3VzIHllYXIsIGEgZmlybSB0aGF0IHRlbmRzIHRvIG9yaWdpbmF0ZSBpdHMgb3duIGRlYWxzIG9yIHRlbmRzIHRvIGludmVzdCBpbiBlYXJseS1zdGFnZSBzdGFydHVwcyBpcyBtb3JlIGxpa2VseSB0byBoYXZlIGxlc3MgZGl2ZXJzaWZpZWQgaW52ZXN0bWVudCBwcm9maWxlIGluIHRoaXMgeWVhci4gDQoNCg0KDQojIyBRdWVzdGlvbiAxYw0KTmV4dCwgbGV0J3MgY2hlY2sgdGhlIHNoYXBlIG9mIHRoZSByZWdyZXNzaW9uIGN1cnZlIHRvIGdldCBhIHNlbnNlIG9mIHRoZSBwYXJhYm9saWMgY3VydmF0dXJlLiANCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI0ZpcnN0LCByZS1ydW4gdGhlIHJlZ3Jlc3Npb24gZnJvbSAxQiBqdXN0IHVzaW5nIGxhZ2dlZCBzdGF0dXMgYW5kIHRoZSBzdGF0dXMgc3F1YXJlZCB0ZXJtIGFuZCBub3QgdXNpbmcgYW55IG9mIHRoZSBhZGRpdGlvbmFsIGNvbnRyb2xzLg0KcmVnXzFjIDwtZ2xtKG53IH4gbGFnX3N0YXR1cyArIEkobGFnX3N0YXR1c14yKSwgcTFiLCBmYW1pbHkgPSBxdWFzaWJpbm9taWFsKGxpbmsgPSAibG9naXQiKSkNCg0KI3NldCB1cCBhIGRhdGEgb2JqZWN0IHdpdGggYSByYW5nZSBvZiB2YWx1ZXMgb2YgdGhlIGxhZ2dlZCBzdGF0dXMgdmFyaWFibGUtMTAwIHZhbHVlcyByYW5naW5nIGZyb20gdGhlIG1pbmltdW0gdG8gdGhlIG1heGltdW0gb2YgdGhpcyB2YXJpYWJsZS4NCmRhdGEgPC0gZGF0YS5mcmFtZShzZXEobWluKHExYiRsYWdfc3RhdHVzLG5hLnJtPVRSVUUpLCBtYXgocTFiJGxhZ19zdGF0dXMsbmEucm09VFJVRSksIGxlbmd0aCA9IDEwMCkpDQpjb2xuYW1lcyhkYXRhKSA8LSAnbGFnX3N0YXR1cycNCnByZWRzIDwtcHJlZGljdChyZWdfMWMsZGF0YSxzZS5maXQgPSBUUlVFKQ0KDQoNCiMgUGxvdA0KcGxvdCh4ID0gZGF0YSRsYWdfc3RhdHVzLCB5ID0gcHJlZHMkZml0LHR5cGUgPSAnbCcseGxhYj0iTGFnZ2VkIFN0YXR1cyIsIHlsYWI9IkRpdmVyc2k/Pz9jYXRpb24gKE5pY2hlIFdpZHRoKSIpDQpwb2x5Z29uKGMoZGF0YSRsYWdfc3RhdHVzLHJldihkYXRhJGxhZ19zdGF0dXMpKSxjKHByZWRzJGZpdC0xLjk1KnByZWRzJHNlLmZpdCxyZXYocHJlZHMkZml0KzEuOTUqcHJlZHMkc2UuZml0KSksY29sID0gcmdiKDEsIDAsIDAsMC41KSwgYm9yZGVyID0gTkEpDQoNCmxpbmVzKHg9IGRhdGEkbGFnX3N0YXR1cywgeSA9IHByZWRzJGZpdCsxLjk2KnByZWRzJHNlLmZpdCwgbHR5ID0gJ2Rhc2hlZCcsIGNvbCA9ICdibHVlJykNCmxpbmVzKHg9IGRhdGEkbGFnX3N0YXR1cywgeSA9IHByZWRzJGZpdC0xLjk2KnByZWRzJHNlLmZpdCwgbHR5ID0gJ2Rhc2hlZCcsIGNvbCA9ICdibHVlJykNCg0KYGBgDQoNCg0KIyMjIElOU0lHSFQNCg0KV2hhdCBkb2VzIHRoZSBjdXJ2ZSBzdWdnZXN0IGFib3V0IHRoZSBkaXZlcnNpZmljYXRpb24gc3RyYXRlZ2llcyBvZiBsb3csIG1pZGRsZSwgYW5kIGhpZ2gtc3RhdHVzIHZlbnR1cmUgY2FwaXRhbCBmaXJtcz8NCg0KVGhlIGN1cnZlIHN1Z2dlc3RzIHRoYXQgaGlnaC1zdGF0dXMgdmVudHVyZSBjYXBpdGFsIGFuZCBsb3cgc3RhdHVzIHZlbnR1cmUgY2FwaXRhbCBoaWF2ZSBsb3dlciBkaXZlcnNpZmljYXRpb24gaW4gdGhlaXIgaW52ZXN0bWVudCBwcm9mb2xpbyB3aGlsZSBtaWRkbGUgc3RhdHVzIHZlbnR1cmUgY2FwaXRhbCBmaXJtcyB0ZW5kIHRvIGhhdmUgaGlnaGVyIGRpdmVyc2lmaWNhdGlvbi4gRmlybXMgd2l0aCBleHRyZW0gaGlnaCBzdGF0dXMgaGF2ZSBldmVuIGxvd2VyIGRpdmVyc2lmaWNhdGlvbiBzdHJhdGVnaWVzIGNvbXBhcmVkIHRvIGZpcm1zIHdpdGggZXh0cmVtIGxvdyBzdGF0dXMuDQoNCkFzIHdlIGFsc28gcGxvdCB0aGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciB0aGUgZml0dGVkIHZhbHVlcywgd2UgY2FuIG9ic2VydmUgZnJvbSB0aGUgcGxvdCB0aGF0IG1pZGRsZS1zdGF0dXMgdmVudHVyZSBjYXBpdGFsIGFyZSBtb3JlIHZhcmllZCBpbiB0aGVpciBsZXZlbCBvZiBkaXZlcnNpZmljYXRpb24gd2hpbGUgbG93LXN0YXR1cyB2ZW50dXJlIGNhcGl0YWwgZG8gbm90IHZhaXJlZCBtdWNoIGluIHRoZSBkaXZlcnNpZmljYXRpb24gc3RyYXRlZ2llcy4NCg0KDQojIyBRdWVzdGlvbiAyDQpXaGljaCB2ZW50dXJlIGNhcGl0YWwgZmlybXMgYXJlIG1vcmUgZWZmZWN0aXZlIGF0IGRpdmVyc2lmeWluZyB0aGVpciBwb3J0Zm9saW9zPyANCg0KIyMjIEENCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0YTJhIDwtIGRhdGFjMw0KZGF0YTJhWywgdHlwZSA6PSBpZmVsc2UoRGVhbF9UeXBlXzE9PSJNZXJnZXIvQWNxdWlzaXRpb24ifERlYWxfVHlwZV8xPT0iSVBPInxEZWFsX1R5cGVfMT09IkJ1eW91dC9MQk8iLDEsMCldDQoNCiNncm91cCBieSBlYWNoIHllYXIvZmlybSBmb3IgbnVtYmVyIG9mIGN1bSBzdWNjZXNzZnVsIGludmVzdG1lbnQNCmRhdGEyYXIgPC0gZGF0YTJhICU+JQ0KICBncm91cF9ieShJbnZlc3Rvcl9JZCxZZWFyKSAlPiUNCiAgc3VtbWFyaXNlKHllYXJzdWNjPXN1bSh0eXBlKSklPiUNCiAgZ3JvdXBfYnkoSW52ZXN0b3JfSWQpICU+JQ0KICBtdXRhdGUodG90YWxzdWNjPWN1bXN1bSh5ZWFyc3VjYykpDQpkYXRhMmFyIDwtIGFzLmRhdGEudGFibGUoZGF0YTJhcikNCg0KDQpgYGANCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojcmVncmVzc2lvbg0KI1J1biBhIGFwcHJvcHJpYXRlIHJlZ3Jlc3Npb24sY29uc2lkZXJpbmcgdGhlIGZvcm0gb2YgdGhlIG91dGNvbWUgdmFyaWFibGUgYW5kIGluY29ycG9yYXRpbmcgdmVudHVyZSBjYXBpdGFsIGZpcm0gZml4ZWQgZWZmZWN0cywgcHJlZGljdGluZyB0aGUgbnVtYmVyIG9mIHN1Y2Nlc3NmdWwgaW52ZXN0bWVudHMgYXMgYSBmdW5jdGlvbiBvZiBsYWdnZWQgc3RhdHVzLCBsYWdnZWQgZGl2ZXJzaWZpY2F0aW9uLCBhbmQgaW50ZXJhY3Rpb24gb2YgbGFnZ2VkIHN0YXR1cyBhbmQgbGFnZ2VkIGRpdmVyc2lmaWNhdGlvbi4gDQojVXNlIHRoZSBuaWNoZSB3aWR0aCBtZWFzdXJlIG9mIGRpdmVyc2lmaWNhdGlvbiBhbmQgaW5jbHVkZSB0aGUgc2FtZSBjb250cm9scyBmcm9tIHRoZSByZWdyZXNzaW9ucyBmcm9tIDFBIGFuZCAxQi4gDQoNCiNnZXQgbGFnIGRpdmVyc2lmaWNhdGlvbg0KcTJhIDwtIG1lcmdlKHExYixkYXRhMmFyLGJ5PWMoIkludmVzdG9yX0lkIiwiWWVhciIpKQ0KDQpxMmEgPC0gcTJhICU+JQ0KICAgIGdyb3VwX2J5KEludmVzdG9yX0lkKSAlPiUNCiAgICBtdXRhdGUobGFnX253ID0gZHBseXI6OmxhZyhudywgbiA9IDEsIGRlZmF1bHQgPSBOQSkpDQoNCg0KIyBSZWdyZXNzaW9uDQpzdW1tYXJ5KGdsbSh0b3RhbHN1Y2MgPz8/IGxhZ19zdGF0dXMgKyBsYWdfbncgKyBsYWdfc3RhdHVzOmxhZ19udyArIGxhZ19maXJzdCArIGxhZ19JVCArIGxhZ19lYXJseSArIFllYXIgLCBxMmEsZmFtaWx5ID0gcG9pc3NvbikpDQoNCg0KDQpgYGANCg0KDQojIyBJTlNJR0hUDQoNCklzIHRoaXMgaW50ZXJhY3Rpb24gcmVsYXRlZCB0byBoYXZpbmcgbW9yZSBzdWNjZXNzZnVsIGludmVzdG1lbnRzPw0KDQpUaGlzIGludGVyYWN0aW9uIGhhcyBwb3NpdGl2ZSBjb2VmZmljaWVudCB3aXRoIGhpZ2hseSBzaWdpbmlmaWNhbmNlLiBJdCBzdWdnZXN0cyB0aGF0IHRoaXMgaW50ZXJhY3Rpb24gaXMgcmVsYXRlZCB0byBoYXZpbmcgbW9yZSBzdWNjZXNzZnVsIGludmVzdG1lbnQuIEJvdGggbGFnX3N0YXR1cyBhbmQgbGFnX253KGRpdmllcnNpZmljYXRpb24pIGhhdmUgc2lnbmlmaWNhbnQgZWZmZWN0IGZyb20gdGhlIHJlZ3Jlc3Npb24sIGFuZCBsYWdfc3RhdHVzIGhhcyBuZWdhdGl2ZSBlZmZlY3Qgd2hpbGUgbGFnX253IGhhcyBwb3NpdGl2ZSBlZmZlY3QuIA0KDQpJdCBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBhIHN5bmVyZ2lzdGljIGVmZmVjdCBvZiB0aGUgdHdvIHZhcmlhYmxlcy1oaWdoIGxldmVscyBvZiBib3RoIHRvZ2V0aGVyKGhpZ2gtc3RhdHVzIHdpdGggaGlnaCBkaXZlcnNpZmljYXRpb24gbGV2ZWwgb2YgdGhlIGludmVzdG1lbnQgcHJvZm9saW8pIGhhdmUgYSBwb3NpdGl2ZSBlZmZlY3Qgb24gdGhlIG91dGNvbWUgdmFyaWFibGUtbW9yZSBzdWNjZXNzZnVsIGludmVzdG1lbnRzLiAgDQoNCg0KDQojIyBCDQoNClNpbWlsYXIgdG8gMUMsIHdlIGNhbiB1c2UgYSB2aXN1YWxpemF0aW9uIHRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdmFyaWFibGVzIGluIHRoZSByZWdyZXNzaW9uLiBXZSBjYW4gYWNjb21wbGlzaCB0aGlzIHVzaW5nIGEgM2Qgc2NhdHRlcnBsb3Qgb3IgYSBjb250b3VyIHBsb3QgZ2VuZXJhdGVkIGZyb20gdGhlID8/P3R0ZWQgdmFsdWVzIG9mIHRoZSBtb2RlbC4gDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNSZS1ydW4gYSBzaW1pbGFyIG1vZGVsIGZyb20gMkEgd2l0aCBqdXN0IGxhZ2dlZCBzdGF0dXMgYW5kIGxhZ2dlZCBkaXZlcnNpZmljYXRpb24gYW5kIHdpdGhvdXQgdXNpbmcgZmlybSBmaXhlZCBlZmZlY3RzLA0KI2UuZy4sdXNpbmcgZ2xtKCl3aXRoZmFtaWx5ID0gInBvaXNzb24iLGFuZCBhc3NpZ24gaXQgdG8gYW4gb2JqZWN0LiANCg0KcmVnXzJiIDwtIGdsbSh0b3RhbHN1Y2MgPz8/IGxhZ19zdGF0dXMgKyBsYWdfbncsIHEyYSxmYW1pbHkgPSBwb2lzc29uKQ0KDQoNCiNOZXh0LCBnZW5lcmF0ZSBhIHJhbmdlIG9mdmFsdWVzIGZvciBsYWdnZWQgc3RhdHVzIGFuZCBsYWdnZWQgZGl2ZXJzaWZpY2F0aW9uLCBzaW1pbGFyIHRvIDFDLiBVc2UgdGhlIGZ1bmN0aW9uIGV4cGFuZC5ncmlkKCkgdG8gcmFuZ2Ugb2YgY29tYmluYXRpb25zIG9mIHN0YXR1cyBhbmQgZGl2ZXJzaWZpY2F0aW9uDQpkYXRhIDwtIGRhdGEuZnJhbWUoc2VxKG1pbihxMmEkbGFnX3N0YXR1cyxuYS5ybT1UUlVFKSwgbWF4KHEyYSRsYWdfc3RhdHVzLG5hLnJtPVRSVUUpLCBsZW5ndGggPSAxMDApLHNlcShtaW4ocTJhJGxhZ19udyxuYS5ybT1UUlVFKSwgbWF4KHEyYSRsYWdfbncsbmEucm09VFJVRSksIGxlbmd0aCA9IDEwMCkpDQpjb2xuYW1lcyhkYXRhKSA8LSBjKCdsYWdfc3RhdHVzJywnbGFnX253JykNCg0KDQojYW5kIHRoZW4gdXNlIHByZWRpY3QgdG8gZ2V0IHRoZSBmaXR0ZWQgdmFsdWVzIGZvciBlYWNoIGNvbWJpbmF0aW9uIG9mIGRpdmVyc2lmaWNhdGlvbiBhbmQgc3RhdHVzLiBCZWxvdyBpcyBzb21lIGNvZGUgdGhhdCB3aWxsIGdlbmVyYXRlIGEgM2Qgc2NhdHRlcnBsb3QuIA0KZGF0YSA8LSBleHBhbmQuZ3JpZChkYXRhKSANCg0KcHJlZHMgPC1wcmVkaWN0KHJlZ18yYixkYXRhKQ0KdmFsdWVzIDwtIGNiaW5kKGRhdGEscHJlZHMpDQpjb2xuYW1lcyh2YWx1ZXMpPC1jKCJzdGF0dXMiLCJkaXZlcnNpZmljYXRpb24iLCJzdWNjZXNzZnVsX2ludmVzdG1lbnRzIikNCmBgYA0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShyZ2wpDQpsaWJyYXJ5KHBsb3QzRCkNCmxpYnJhcnkocGxvdGx5KQ0KDQojIHJlZ3VsYXIgM2QgcGxvdCANCnNjYXR0ZXIzRCh2YWx1ZXMkZGl2ZXJzaWZpY2F0aW9uLCB2YWx1ZXMkc3RhdHVzLCB2YWx1ZXMkc3VjY2Vzc2Z1bF9pbnZlc3RtZW50cykNCg0KYGBgDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBpbnRlcmFjdGl2ZSAzZCBwbG90DQpwbG90M2QodmFsdWVzJGRpdmVyc2lmaWNhdGlvbiwgdmFsdWVzJHN0YXR1cywgdmFsdWVzJHN1Y2Nlc3NmdWxfaW52ZXN0bWVudHMpIA0KDQpgYGANCg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgQSBjb250b3VyIHBsb3QgY2FuIGJlIGV4ZWN1dGVkIGluIGEgc2ltaWxhciBtYW5uZXIgdXNpbmcgdGhlIGZvbGxvd2luZyBjb2RlLCBmcm9tIHRoZSBwbG90bHkgcGFja2FnZS4NCmNvbG5hbWVzKHZhbHVlcyk8LWMoInN0YXR1cyIsIm5pY2hlX3dpZHRoIiwiZml0IikNCnAxID0gcGxvdF9seSgNCiAgdmFsdWVzLA0KICB4ID0gfnN0YXR1cywgDQogIHkgPSB+bmljaGVfd2lkdGgsDQogIHogPSB+Zml0LCANCiAgdHlwZSA9ICJjb250b3VyIiwNCiAgYXV0b2NvbnRvdXIgPSBGQUxTRSwgDQogIGNvbnRvdXJzID0gbGlzdCggZW5kID0gbWF4KHZhbHVlcyRmaXQsIG5hLnJtID0gVFJVRSksIA0KICAgICAgICAgICAgICAgICAgIHNpemUgPSBhYnMobWF4KHZhbHVlcyRmaXQsIG5hLnJtID0gVFJVRSkgLSBtaW4odmFsdWVzJGZpdCwgbmEucm0gPSBUUlVFKSkvMjAsDQogICAgICAgICAgICAgICAgICAgc3RhcnQgPSBtaW4odmFsdWVzJGZpdCwgbmEucm0gPSBUUlVFKSwgc2hvd2xpbmVzID0gRkFMU0UgKSwNCiAgbGluZSA9IGxpc3Qoc21vb3RoaW5nID0gMC44NSksDQogIGNvbG9yc2NhbGUgPSAiR3JleXMiIA0KICApICU+JSANCiAgY29sb3JiYXIobGVuID0gMSwgbnRpY2tzID0gMTAsIHRpdGxlID0gIkVzdGltYXRlZCBzdWNjZXNzZnVsIFxuIGludmVzdG1lbnRzIikgJT4lIA0KICBsYXlvdXQoeWF4aXMgPSBsaXN0KHRpdGxlID0gIk5pY2hlIHdpZHRoIikpICU+JSANCiAgbGF5b3V0KHhheGlzID0gbGlzdCh0aXRsZSA9ICJTdGF0dXMiKSkgDQpwMQ0KDQpgYGANCg0KIyMgSU5TSUdIVA0KDQpXaGF0IGRvIHRoZSBwYXR0ZXJucyBzdWdnZXN0IGFib3V0IHdoaWNoIHZlbnR1cmUgY2FwaXRhbCBmaXJtcyBhcmUgbW9zdCBvciBsZWFzdCBzdWNjZXNzZnVsIG92ZXJhbGwgYXQgZGl2ZXJzaWZ5aW5nIHRoZWlyIHBvcnRmb2xpb3M/DQoNCkFjY29yZGluZyB0byBhYm92ZSBwYXR0ZXJucywgd2UgY2FuIGNvbmNsdWRlIHRoYXQgZmlybXMgd2l0aCBsb3dlciBzdGF0dXMsIGxvd2VyIGRpdmVyc2lmaWNhdGlvbiBsZXZlbCB0ZW5kIHRvIGhhdmUgbW9yZSBzdWNjZXNzZnVsIGludmVzdG1lbnQuIEl0IHN1Z2dlc3RzIHRoYXQgd2l0aCBzYW1lIGFtb3VudCBvZiBzdWNjZXNzZnVsIGludmVzdG1lbnRzLCBsb3ctc3RhdHVzIHZlbnR1cmUgY2FwaXRhbHMgZGl2ZXJzaWZ5IHRoZWlyIHBvcnRmb2xpb3MgbW9yZSBlZmZlY3RpdmUgYW5kIGhhdmUgaGlnaGVyIGxldmVsIG9mIGRpdmVyc2lmaWNhdGlvbi4NCg0KDQojIyBRdWVzdGlvbiAzDQpUaGUgcGFyYWJvbGljIHJlbGF0aW9uc2hpcHMgZnJvbSAxQiBhbmQgMUMgc3VnZ2VzdCB0aGF0IGxvdyBhbmQgaGlnaC1zdGF0dXMgdmVudHVyZSBjYXBpdGFsIGZpcm1zIG1heSBzaGFyZSBzaW1pbGFyIHRlbmRlbmNpZXMgdG8gZGl2ZXJzaWZ5LCBidXQgdGhlIGVzdGltYXRlcyBmcm9tIDJBIHN1Z2dlc3QgdGhhdCBoaWdoc3RhdHVzIGZpcm1zIGFyZSBiZXR0ZXIgYXQgZGl2ZXJzaWZ5aW5nLiBXaHkgbWlnaHQgdGhpcyBiZSB0aGUgY2FzZT8NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojbm8gdGltZSB0byBydW4gdGhpcyBwYXJ0IG9mIGNvZGUgYnV0IGhhdmUgdGhvdWdodCBhYm91dCB0aGUgbG9naWMgYW5kIHNob3cgaGVyZQ0KDQojIENyZWF0ZSBhbiBlbXB0eSBkYXRhdGFibGUgdG8gc3RvcmUgaW5mb3JtYXRpb24gYWJvdXQgZWFjaCBpbnZlc3RvcidzIGNvb3JkaW5hdGVzDQpjb29yZCA8LSBkYXRhLnRhYmxlKCkNCg0KZm9yKGkgaW4geWVhcmxpc3Qpew0KICAjIEZvciBlYWNoIHllYXIsIHRha2UgYSBzdWItZGF0YXNldCBvZiBwcmV2aW91cyB5ZWFycy4NCiAgaW52ZXN0X3N1YiA8LSBhcy5kYXRhLnRhYmxlKHN1YnNldChkYXRhNSwgeWVhcjw9aSkpDQogICMgRmlyc3QgY3JlYXRlIGFuIGFmZmlsaWF0aW9uIG1hdHJpeC4gMSBpbmRpY2F0ZXMgdGhhdCB0aGlzIGluZHVzdHJ5IGNhdGVnb3J5IGhhcyBvY2N1cmVkIGluIHRoZSBmaXJtJ3MgcG9ydGZvbGlvLg0KICBqYWNfZGlzdCA8LSBhcy5kYXRhLmZyYW1lKGludmVzdF9zdWJbLGMoMyw2KV0pDQogIGphY19kaXN0IDwtIHVuaXF1ZShuYS5vbWl0KGphY19kaXN0KSkNCiAgamFjX2Rpc3Qkb2NjdXIgPC0gMQ0KICBqYWNfZGlzdF9tYXRyaXggPC0gYWNhc3QoamFjX2Rpc3QsSW52ZXN0b3JfSWQgfiBQcmltYXJ5X0luZHVzdHJ5X0NvZGUsdmFsdWUudmFyPSJvY2N1ciIpDQogIGphY19kaXN0X21hdHJpeFtpcy5uYShqYWNfZGlzdF9tYXRyaXgpXSA9IDANCiAgamFjX2Rpc3RfbWF0cml4W2phY19kaXN0X21hdHJpeD49MV0gPSAxDQogICMgVXNlIGEgbXVsdGlkaW1lbnNpb25hbCBzY2FsaW5nIG9mIHR3byBkaW1lbnNpb25zIHRvIGRldGVybWluZSB0aGUgcG9zaXRpb24gDQogIGNvb3JkX3Jlc3VsdCA8LWFzLmRhdGEuZnJhbWUoY21kc2NhbGUoYXMuZGF0YS5mcmFtZShhcy5tYXRyaXgocHJveHk6OmRpc3QoamFjX2Rpc3RfbWF0cml4LG1ldGhvZCA9ImphY2NhcmQiKSkpKSkNCiAgY29sbmFtZXMoY29vcmRfcmVzdWx0KSA8LSBjKCdDMScsJ0MyJykNCiAgY29vcmRfcmVzdWx0JEludmVzdG9yX0lkIDwtIHJvd25hbWVzKGphY19kaXN0X21hdHJpeCkNCiAgDQogICMgQ29tYmluZSB0aGlzIHllYXIncyBpbmZvcm1hdGlvbiB0byB0aGUgbWFpbiBjb25jZW50cmF0aW9uX3Njb3JlIGRhdGF0YWJsZQ0KICBjb29yZF9yZXN1bHQkeWVhciA8LSBpDQogIGNvb3JkICA8LSByYmluZChjb29yZCwgY29vcmRfcmVzdWx0KQ0KfQ0KDQoNCmNvb3JkIDwtIGZyZWFkKCJjb29yZC5jc3YiLGhlYWRlciA9IFRSVUUpDQppbmR1c3RyeV9tZWRvaWRzIDwtIGRhdGE1WyxjKCJJbnZlc3Rvcl9JZCIsIkRlYWxfSWQiLCJQcmltYXJ5X0luZHVzdHJ5X0NvZGUiLCJZZWFyIildDQppbmR1c3RyeV9tZWRvaWRzIDwtIGFzLmRhdGEudGFibGUoaW5kdXN0cnlfbWVkb2lkcykNCmluZHVzdHJ5X21lZG9pZHNbLGNvdW50Oj0uTiwgYnk9YygiWWVhciIsIlByaW1hcnlfSW5kdXN0cnlfQ29kZSIsIkludmVzdG9yX0lkIildDQoNCiMgSWYgYSB2ZW50dXJlIGNhcGl0YWwgZmlybSB0aGF0IG9ubHkgaW52ZXN0cyBpbiB0aGF0IGNhdGVnb3J5IGluIGEgcGFydGljdWxhciB5ZWFyLCBpdCBzaG91bGQgaW5zdGVhZCBiZWNvbWUgdGhlIG1lZG9pZC4NCmluZHVzdHJ5X21lZG9pZHNbLG1lZG9pZDo9IGlmZWxzZShsZW5ndGgodW5pcXVlKFByaW1hcnlfSW5kdXN0cnlfQ29kZSkpPT0xLDEsMCksIGJ5PWMoJ1llYXInLCdJbnZlc3Rvcl9JZCcpXQ0KDQojIENoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYSBtZWRvaWQgZm9yIHRoaXMgaW5kdXN0cnkgYWZ0ZXIgdGhlIGZpcnN0IHN0ZXAuDQppbmR1c3RyeV9tZWRvaWRzWyxtZWRvaWRfZXhpc3Q6PSBpZmVsc2Uoc3VtKG1lZG9pZCk+MCwxLDApLCBieT1jKCdZZWFyJywnUHJpbWFyeV9JbmR1c3RyeV9Db2RlJyldDQoNCiMgVGhlbiBpZiBubyA/Pz9ybXMgaW52ZXN0IGV4Y2x1c2l2ZWx5IGluIHRoZSBjYXRlZ29yeSwgSSBqdXN0IHVzZWQgYXMgdGhlIG1lZG9pZCB0aGUgPz8/cm0gd2l0aCB0aGUgbW9zdCBpbnZlc3RtZW50cyBpbiB0aGlzIGNhdGVnb3J5LiANCmluZHVzdHJ5X21lZG9pZHNbLG1lZG9pZDo9IGlmZWxzZShtZWRvaWRfZXhpc3Q9PTAsY291bnQ9PW1heChjb3VudCksbWVkb2lkKSxieT1jKCdZZWFyJywnUHJpbWFyeV9JbmR1c3RyeV9Db2RlJyldDQoNCiMgRG91YmxlIGNoZUNLIHRoZXJlIGlzIGEgbWVkb2lkIGZvciBldmVyeSByb3cncyBjYXRlZ29yeS4NCmluZHVzdHJ5X21lZG9pZHNbLG1lZG9pZF9leGlzdDI6PSBpZmVsc2Uoc3VtKG1lZG9pZCk+MCwxLDApLCBieT1jKCdZZWFyJywnUHJpbWFyeV9JbmR1c3RyeV9Db2RlJyldDQoNCg0KIyBPbmx5IGtlZXAgbWVkb2lkIG9mIGluZHVzdHJ5IGNhdGVnb3J5IGluIHRoZSBkYXRhIHRhYmxlDQppbmR1c3RyeV9tZWRvaWRzIDwtIGluZHVzdHJ5X21lZG9pZHNbbWVkb2lkPT0xXVssYygxLDMsNCldDQppbmR1c3RyeV9tZWRvaWRzIDwtIGxlZnRfam9pbihpbmR1c3RyeV9tZWRvaWRzLCBjb29yZFssYygyOjUpXSwgYnk9YygnWWVhcicsJ0ludmVzdG9yX0lkJykpDQojIE9ubHkga2VlcCBvbmUgbWVkb2lkIGZvciBlYWNoIGNhdGVncm95IGluIGVhY2ggeWVhcg0KaW5kdXN0cnlfbWVkb2lkcyA8LSBhcy5kYXRhLnRhYmxlKGluZHVzdHJ5X21lZG9pZHMpDQppbmR1c3RyeV9tZWRvaWRzIDwtIGluZHVzdHJ5X21lZG9pZHNbLCBoZWFkKC5TRCwgMSksIGJ5PWMoJ1llYXInLCdQcmltYXJ5X0luZHVzdHJ5X0NvZGUnKV0NCmNvbG5hbWVzKGluZHVzdHJ5X21lZG9pZHMpWzM6NV0gPC0gYygnTWVkb2lkJywiTWVkb2lkX0MxIiwiTWVkb2lkX0MyIikNCg0KDQojIEpvaW4gY29vcmRpbmF0ZXMgb2YgZWFjaCBkZWFsIGFuZCBtZWRvaWQgY29vcmRpbmF0ZSBvZiBlYWNoIGNhdGVnb3J5IGJhY2sgdG8gdGhlIG1haW4gZGF0YSB0YWJsZQ0KZGF0YTNhIDwtIGRhdGE1DQpkYXRhM2EgPC0gbGVmdF9qb2luKGRhdGEzYSwgY29vcmQsIGJ5PWMoJ3llYXInLCdJbnZlc3Rvcl9JZCcpKQ0KZGF0YTNhIDwtIGxlZnRfam9pbihkYXRhM2EsIGluZHVzdHJ5X21lZG9pZHNbLGMoMSwyLDQsNSldLCBieT1jKCd5ZWFyJywnUHJpbWFyeV9JbmR1c3RyeV9Db2RlJykpDQpkYXRhM2EgPC1hcy5kYXRhLnRhYmxlKGRhdGEzYSkNCg0KIyBGb3IgZWFjaCBkZWFsLCBkZT8/P25lIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIGEgPz8/cm0ncyBleHBlcmllbmNlIGFuZCB0aGUgaW5kdXN0cnkgY2F0ZWdvcnkgDQpkYXRhM2FbLGV4cGVyaWVuY2VfZGlmZmVuY2U6PSBzcXJ0KChNZWRvaWRfQzEtQzEpXjIrKE1lZG9pZF9DMi1DMileMildDQoNCiMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIGRpc3RhbmNlIGJldHdlZW4gYSA/Pz9ybSdzIHN5bmRpY2F0ZSBwYXJ0bmVycyBhbmQgdGhlIGluZHVzdHJ5IGNhdGVnb3J5IG1lZG9pZHMgZm9yIHRoZSBkZWFscyB0aGF0IGl0IGludmVzdHMgaW4gaW4gYSBnaXZlbiB5ZWFyDQojIEZpcnN0IHN1bSB0aGUgZGlmZmVyZW5jZXMgYnkgZGVhbCBlYWNoIHllYXINCmRhdGEzYVssRGVhbF9TdW06PSBzdW0oZXhwZXJpZW5jZV9kaWZmZW5jZSksYnk9YygnWWVhcicsJ0RlYWxfSWQnKV0NCiMgVGhlbiBzdW0gdGhlIGRpZmZlcmVuY2VzIG9mIGFsbCB0aGUgZGVhbHMgdGhhdCBhbiBpbnZlc3RvciBpbnZlc3QgaW4gZWFjaCB5ZWFyDQpkYXRhM2FbLEludmVzdG9yX1BhcnRuZXJzX1N1bTo9c3VtKERlYWxfU3VtKSxieT1jKCdZZWFyJywnSW52ZXN0b3JfSWQnKSBdDQoNCg0KDQpgYGANCg0KcmVncmVzc2lvbg0KYGBge3J9DQojUnVuIGEgYXBwcm9wcmlhdGUgcmVncmVzc2lvbiwgY29uc2lkZXJpbmcgdGhlIGZvcm0gb2YgdGhlIG91dGNvbWUgdmFyaWFibGUgYW5kIGluY29ycG9yYXRpbmcgdmVudHVyZSBjYXBpdGFsID8/P3JtID8/P3hlZCBlZmZlY3RzLCBwcmVkaWN0aW5nIHRoZSBhdmVyYWdlIGRpc3RhbmNlIGJldHdlZW4gYSA/Pz9ybSdzIHN5bmRpY2F0ZSBwYXJ0bmVycyBhbmQgdGhlIGluZHVzdHJ5IGNhdGVnb3J5IG1lZG9pZHMgZm9yIHRoZSBkZWFscyB0aGF0IGl0IGludmVzdHMgaW5pbmFnaXZlbnllYXIsYXMgYSBmdW5jdGlvbiBvZiBhIGZpcm0ncyBsYWdnZWQgc3RhdHVzLHRoZSBmaXJtJ3Mgb3duIGF2ZXJhZ2UgZGlzdGFuY2UgZnJvbSB0aGUgaW5kdXN0cnkgY2F0ZWdvcnkgbWVkb2lkcyBmb3IgdGhlIGRlYWxzIHRoYXQgaXQgaW52ZXN0cyBpbiBpbiBhIGdpdmVuIHllYXIsIGFuZCB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGVzZSBzdHdvIHZhcmlhYmxlcy4gDQoNCnN1bW1hcnkobG0oYXZnX3BhcnRuZXJfZGlzdGFuY2VzID8/PyBhdmdfb3duX2Rpc3RhbmNlcyArIGxhZ19zdGF0dXMgKyBhdmdfb3duX2Rpc3RhbmNlczpsYWdfc3RhdHVzICsgbGFnX2ZpcnN0ICsgbGFnX0lUICsgbGFnX2Vhcmx5ICsgWWVhciwgZGF0YTNhKSkNCmBgYA0KDQoNCiMjIEINCg0Kc2FtZSBtZXRob2Qgd2l0aCBxdWVzdGlvbiAyDQpgYGB7cn0NCiMgcmVndWxhciAzZCBwbG90IA0KcGxvdHEzIDwtIHNjYXR0ZXIzRCh2YWx1ZXMkb3duX2Rpc3RhbmNlX2Zyb21fdGhlX2luZHVzdHJ5X2NhdGVnb3JpZXMsIHZhbHVlcyRzdGF0dXMsIHZhbHVlcyRwYXJ0bmVyc19kaXN0YW5jZV9mcm9tX3RoZV9pbmR1c3RyeV9TY2F0ZWdvcmllcykNCg0KYGBgDQoNCmBgYHtyfQ0KIyBpbnRlcmFjdGl2ZSAzZCBwbG90DQpwbG90cTNkIDwtIHBsb3QzZCh2YWx1ZXMkb3duX2Rpc3RhbmNlX2Zyb21fdGhlX2luZHVzdHJ5X2NhdGVnb3JpZXMsIHZhbHVlcyRzdGF0dXMsIHZhbHVlcyRwYXJ0bmVyc19kaXN0YW5jZV9mcm9tX3RoZV9pbmR1c3RyeV9TY2F0ZWdvcmllcykgDQpgYGANCg0KYGBge3J9DQojY29sbmFtZXModmFsdWVzKTwtYygib3duX2Rpc3RhbmNlX2Zyb21fdGhlX2luZHVzdHJ5X2NhdGVnb3JpZXMiLCJzdGF0dXMiLCJwYXJ0bmVyc19kaXN0YW5jZV9mcm9tX3RoZV9pbmR1c3RyeV9TY2F0ZWdvcmllcyIpDQpwMyA9IHBsb3RfbHkoDQogIHZhbHVlcywNCiAgeCA9IH5vd25fZGlzdGFuY2VfZnJvbV90aGVfaW5kdXN0cnlfY2F0ZWdvcmllcywgDQogIHkgPSB+c3RhdHVzLA0KICB6ID0gfnBhcnRuZXJzX2Rpc3RhbmNlX2Zyb21fdGhlX2luZHVzdHJ5X1NjYXRlZ29yaWVzLCANCiAgdHlwZSA9ICJjb250b3VyIiwNCiAgYXV0b2NvbnRvdXIgPSBGQUxTRSwgDQogIGNvbnRvdXJzID0gbGlzdCggZW5kID0gbWF4KHZhbHVlcyRmaXQsIG5hLnJtID0gVFJVRSksIA0KICAgICAgICAgICAgICAgICAgIHNpemUgPSBhYnMobWF4KHZhbHVlcyRmaXQsIG5hLnJtID0gVFJVRSkgLSBtaW4odmFsdWVzJGZpdCwgbmEucm0gPSBUUlVFKSkvMjAsDQogICAgICAgICAgICAgICAgICAgc3RhcnQgPSBtaW4odmFsdWVzJGZpdCwgbmEucm0gPSBUUlVFKSwgc2hvd2xpbmVzID0gRkFMU0UgKSwNCiAgbGluZSA9IGxpc3Qoc21vb3RoaW5nID0gMC44NSksDQogIGNvbG9yc2NhbGUgPSAiR3JleXMiIA0KICApICU+JSANCiAgY29sb3JiYXIobGVuID0gMSwgbnRpY2tzID0gMTAsIHRpdGxlID0gIkVzdGltYXRlZCBzdWNjZXNzZnVsIFxuIGludmVzdG1lbnRzIikgJT4lIA0KICBsYXlvdXQoeWF4aXMgPSBsaXN0KHRpdGxlID0gIlN0YXR1cyIpKSAlPiUgDQogIGxheW91dCh4YXhpcyA9IGxpc3QodGl0bGUgPSAib3duX2Rpc3RhbmNlX2Zyb21fdGhlX2luZHVzdHJ5X2NhdGVnb3JpZXMiKSkgDQojcDMNCg0KYGBgDQoNCg0K